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

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

Issue 1205033005: Adds selection expansion support for Contextual Search. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed java tests Created 5 years, 5 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 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 23 matching lines...) Expand all
34 const char kContextualSearchSurroundingSizeParamName[] = "surrounding_size"; 34 const char kContextualSearchSurroundingSizeParamName[] = "surrounding_size";
35 const char kContextualSearchIcingSurroundingSizeParamName[] = 35 const char kContextualSearchIcingSurroundingSizeParamName[] =
36 "icing_surrounding_size"; 36 "icing_surrounding_size";
37 const char kContextualSearchResolverURLParamName[] = "resolver_url"; 37 const char kContextualSearchResolverURLParamName[] = "resolver_url";
38 const char kContextualSearchDoNotSendURLParamName[] = "do_not_send_url"; 38 const char kContextualSearchDoNotSendURLParamName[] = "do_not_send_url";
39 const char kContextualSearchResponseDisplayTextParam[] = "display_text"; 39 const char kContextualSearchResponseDisplayTextParam[] = "display_text";
40 const char kContextualSearchResponseSelectedTextParam[] = "selected_text"; 40 const char kContextualSearchResponseSelectedTextParam[] = "selected_text";
41 const char kContextualSearchResponseSearchTermParam[] = "search_term"; 41 const char kContextualSearchResponseSearchTermParam[] = "search_term";
42 const char kContextualSearchResponseResolvedTermParam[] = "resolved_term"; 42 const char kContextualSearchResponseResolvedTermParam[] = "resolved_term";
43 const char kContextualSearchPreventPreload[] = "prevent_preload"; 43 const char kContextualSearchPreventPreload[] = "prevent_preload";
44 const char kContextualSearchMentions[] = "mentions";
44 const char kContextualSearchServerEndpoint[] = "_/contextualsearch?"; 45 const char kContextualSearchServerEndpoint[] = "_/contextualsearch?";
45 const int kContextualSearchRequestVersion = 2; 46 const int kContextualSearchRequestVersion = 2;
46 const char kContextualSearchResolverUrl[] = 47 const char kContextualSearchResolverUrl[] =
47 "contextual-search-resolver-url"; 48 "contextual-search-resolver-url";
48 // The default size of the content surrounding the selection to gather, allowing 49 // The default size of the content surrounding the selection to gather, allowing
49 // room for other parameters. 50 // room for other parameters.
50 const int kContextualSearchDefaultContentSize = 1536; 51 const int kContextualSearchDefaultContentSize = 1536;
51 const int kContextualSearchDefaultIcingSurroundingSize = 400; 52 const int kContextualSearchDefaultIcingSurroundingSize = 400;
53 const int kContextualSearchMaxSelection = 100;
52 // The maximum length of a URL to build. 54 // The maximum length of a URL to build.
53 const int kMaxURLSize = 2048; 55 const int kMaxURLSize = 2048;
54 const char kXssiEscape[] = ")]}'\n"; 56 const char kXssiEscape[] = ")]}'\n";
55 const char kDiscourseContextHeaderPrefix[] = "X-Additional-Discourse-Context: "; 57 const char kDiscourseContextHeaderPrefix[] = "X-Additional-Discourse-Context: ";
56 const char kDoPreventPreloadValue[] = "1"; 58 const char kDoPreventPreloadValue[] = "1";
57 59
58 // The number of characters that should be shown on each side of the selected 60 // The number of characters that should be shown on each side of the selected
59 // expression. 61 // expression.
60 const int kSurroundingSizeForUI = 30; 62 const int kSurroundingSizeForUI = 30;
61 63
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 137 }
136 138
137 void ContextualSearchDelegate::OnURLFetchComplete( 139 void ContextualSearchDelegate::OnURLFetchComplete(
138 const net::URLFetcher* source) { 140 const net::URLFetcher* source) {
139 DCHECK(source == search_term_fetcher_.get()); 141 DCHECK(source == search_term_fetcher_.get());
140 int response_code = source->GetResponseCode(); 142 int response_code = source->GetResponseCode();
141 std::string search_term; 143 std::string search_term;
142 std::string display_text; 144 std::string display_text;
143 std::string alternate_term; 145 std::string alternate_term;
144 std::string prevent_preload; 146 std::string prevent_preload;
147 int mention_start = 0;
148 int mention_end = 0;
149 int start_adjust = 0;
150 int end_adjust = 0;
145 151
146 if (source->GetStatus().is_success() && response_code == 200) { 152 if (source->GetStatus().is_success() && response_code == 200) {
147 std::string response; 153 std::string response;
148 bool has_string_response = source->GetResponseAsString(&response); 154 bool has_string_response = source->GetResponseAsString(&response);
149 DCHECK(has_string_response); 155 DCHECK(has_string_response);
150 if (has_string_response) { 156 if (has_string_response) {
151 DecodeSearchTermsFromJsonResponse(response, &search_term, &display_text, 157 DecodeSearchTermsFromJsonResponse(response, &search_term, &display_text,
152 &alternate_term, &prevent_preload); 158 &alternate_term, &prevent_preload,
159 &mention_start, &mention_end);
160 if (mention_start != 0 || mention_end != 0) {
161 // Sanity check that our selection is non-zero and it is less than
162 // 100 characters as that would make contextual search bar hide.
163 // We also check that there is at least one character overlap between
164 // the new and old selection.
165 if (mention_start >= mention_end
166 || (mention_end - mention_start) > kContextualSearchMaxSelection
167 || mention_end <= context_->start_offset
168 || mention_start >= context_->end_offset) {
169 start_adjust = 0;
170 end_adjust = 0;
171 } else {
172 start_adjust = mention_start - context_->start_offset;
173 end_adjust = mention_end - context_->end_offset;
174 }
175 }
153 } 176 }
154 } 177 }
155 bool is_invalid = response_code == net::URLFetcher::RESPONSE_CODE_INVALID; 178 bool is_invalid = response_code == net::URLFetcher::RESPONSE_CODE_INVALID;
156 search_term_callback_.Run( 179 search_term_callback_.Run(
157 is_invalid, response_code, search_term, display_text, alternate_term, 180 is_invalid, response_code, search_term, display_text, alternate_term,
158 prevent_preload == kDoPreventPreloadValue); 181 prevent_preload == kDoPreventPreloadValue, start_adjust, end_adjust);
159 182
160 // The ContextualSearchContext is consumed once the request has completed. 183 // The ContextualSearchContext is consumed once the request has completed.
161 context_.reset(); 184 context_.reset();
162 } 185 }
163 186
164 // TODO(jeremycho): Remove selected_text and base_page_url CGI parameters. 187 // TODO(jeremycho): Remove selected_text and base_page_url CGI parameters.
165 GURL ContextualSearchDelegate::BuildRequestUrl() { 188 GURL ContextualSearchDelegate::BuildRequestUrl() {
166 // TODO(jeremycho): Confirm this is the right way to handle TemplateURL fails. 189 // TODO(jeremycho): Confirm this is the right way to handle TemplateURL fails.
167 if (!template_url_service_ || 190 if (!template_url_service_ ||
168 !template_url_service_->GetDefaultSearchProvider()) { 191 !template_url_service_->GetDefaultSearchProvider()) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 return true; 415 return true;
393 } 416 }
394 417
395 // Decodes the given response from the search term resolution request and sets 418 // Decodes the given response from the search term resolution request and sets
396 // the value of the given parameters. 419 // the value of the given parameters.
397 void ContextualSearchDelegate::DecodeSearchTermsFromJsonResponse( 420 void ContextualSearchDelegate::DecodeSearchTermsFromJsonResponse(
398 const std::string& response, 421 const std::string& response,
399 std::string* search_term, 422 std::string* search_term,
400 std::string* display_text, 423 std::string* display_text,
401 std::string* alternate_term, 424 std::string* alternate_term,
402 std::string* prevent_preload) { 425 std::string* prevent_preload,
426 int* mention_start,
427 int* mention_end) {
403 bool contains_xssi_escape = response.find(kXssiEscape) == 0; 428 bool contains_xssi_escape = response.find(kXssiEscape) == 0;
404 const std::string& proper_json = 429 const std::string& proper_json =
405 contains_xssi_escape ? response.substr(strlen(kXssiEscape)) : response; 430 contains_xssi_escape ? response.substr(strlen(kXssiEscape)) : response;
406 JSONStringValueDeserializer deserializer(proper_json); 431 JSONStringValueDeserializer deserializer(proper_json);
407 scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, NULL)); 432 scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, NULL));
408 433
409 if (root.get() != NULL && root->IsType(base::Value::TYPE_DICTIONARY)) { 434 if (root.get() != NULL && root->IsType(base::Value::TYPE_DICTIONARY)) {
410 base::DictionaryValue* dict = 435 base::DictionaryValue* dict =
411 static_cast<base::DictionaryValue*>(root.get()); 436 static_cast<base::DictionaryValue*>(root.get());
412 dict->GetString(kContextualSearchPreventPreload, prevent_preload); 437 dict->GetString(kContextualSearchPreventPreload, prevent_preload);
413 dict->GetString(kContextualSearchResponseSearchTermParam, search_term); 438 dict->GetString(kContextualSearchResponseSearchTermParam, search_term);
414 // For the display_text, if not present fall back to the "search_term". 439 // For the display_text, if not present fall back to the "search_term".
415 if (!dict->GetString(kContextualSearchResponseDisplayTextParam, 440 if (!dict->GetString(kContextualSearchResponseDisplayTextParam,
416 display_text)) { 441 display_text)) {
417 *display_text = *search_term; 442 *display_text = *search_term;
418 } 443 }
444 // Extract mentions for selection expansion.
445 base::ListValue* mentions_list;
446 dict->GetList(kContextualSearchMentions, &mentions_list);
447 if (mentions_list != NULL && mentions_list->GetSize() >= 2)
448 ExtractMentionsStartEnd(*mentions_list, mention_start, mention_end);
419 // If either the selected text or the resolved term is not the search term, 449 // If either the selected text or the resolved term is not the search term,
420 // use it as the alternate term. 450 // use it as the alternate term.
421 std::string selected_text; 451 std::string selected_text;
422 dict->GetString(kContextualSearchResponseSelectedTextParam, &selected_text); 452 dict->GetString(kContextualSearchResponseSelectedTextParam, &selected_text);
423 if (selected_text != *search_term) { 453 if (selected_text != *search_term) {
424 *alternate_term = selected_text; 454 *alternate_term = selected_text;
425 } else { 455 } else {
426 std::string resolved_term; 456 std::string resolved_term;
427 dict->GetString(kContextualSearchResponseResolvedTermParam, 457 dict->GetString(kContextualSearchResponseResolvedTermParam,
428 &resolved_term); 458 &resolved_term);
429 if (resolved_term != *search_term) { 459 if (resolved_term != *search_term) {
430 *alternate_term = resolved_term; 460 *alternate_term = resolved_term;
431 } 461 }
432 } 462 }
433 } 463 }
434 } 464 }
435 465
436 // Returns the size of the surroundings to be sent to the server for search term 466 // Returns the size of the surroundings to be sent to the server for search term
437 // resolution. 467 // resolution.
438 int ContextualSearchDelegate::GetSearchTermSurroundingSize() { 468 int ContextualSearchDelegate::GetSearchTermSurroundingSize() {
439 const std::string param_value = variations::GetVariationParamValue( 469 const std::string param_value = variations::GetVariationParamValue(
440 kContextualSearchFieldTrialName, 470 kContextualSearchFieldTrialName,
441 kContextualSearchSurroundingSizeParamName); 471 kContextualSearchSurroundingSizeParamName);
442 int param_length; 472 int param_length;
443 if (!param_value.empty() && base::StringToInt(param_value, &param_length)) 473 if (!param_value.empty() && base::StringToInt(param_value, &param_length))
444 return param_length; 474 return param_length;
445 return kContextualSearchDefaultContentSize; 475 return kContextualSearchDefaultContentSize;
446 } 476 }
447 477
478 // Extract the Start/End of the mentions in the surrounding text
479 // for selection-expansion.
480 void ContextualSearchDelegate::ExtractMentionsStartEnd(
481 const base::ListValue& mentions_list,
482 int* startResult,
483 int* endResult) {
484 int int_value;
485 if (mentions_list.GetInteger(0, &int_value))
486 *startResult = std::max(0, int_value);
487 if (mentions_list.GetInteger(1, &int_value))
488 *endResult = std::max(0, int_value);
489 }
490
448 // Returns the size of the surroundings to be sent to Icing. 491 // Returns the size of the surroundings to be sent to Icing.
449 int ContextualSearchDelegate::GetIcingSurroundingSize() { 492 int ContextualSearchDelegate::GetIcingSurroundingSize() {
450 std::string param_string = variations::GetVariationParamValue( 493 std::string param_string = variations::GetVariationParamValue(
451 kContextualSearchFieldTrialName, 494 kContextualSearchFieldTrialName,
452 kContextualSearchIcingSurroundingSizeParamName); 495 kContextualSearchIcingSurroundingSizeParamName);
453 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 496 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
454 kContextualSearchIcingSurroundingSizeParamName)) { 497 kContextualSearchIcingSurroundingSizeParamName)) {
455 param_string = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 498 param_string = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
456 kContextualSearchIcingSurroundingSizeParamName); 499 kContextualSearchIcingSurroundingSizeParamName);
457 } 500 }
(...skipping 23 matching lines...) Expand all
481 end_offset -= trim; 524 end_offset -= trim;
482 } 525 }
483 if (result_text.length() > end_offset + padding_each_side_pinned) { 526 if (result_text.length() > end_offset + padding_each_side_pinned) {
484 // Trim the end. 527 // Trim the end.
485 result_text = result_text.substr(0, end_offset + padding_each_side_pinned); 528 result_text = result_text.substr(0, end_offset + padding_each_side_pinned);
486 } 529 }
487 *start = start_offset; 530 *start = start_offset;
488 *end = end_offset; 531 *end = end_offset;
489 return result_text; 532 return result_text;
490 } 533 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698