OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/search/search.h" | 5 #include "chrome/browser/search/search.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/rand_util.h" |
10 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/google/google_util.h" | 15 #include "chrome/browser/google/google_util.h" |
15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/profiles/profile_manager.h" | 17 #include "chrome/browser/profiles/profile_manager.h" |
17 #include "chrome/browser/search/instant_service.h" | 18 #include "chrome/browser/search/instant_service.h" |
18 #include "chrome/browser/search/instant_service_factory.h" | 19 #include "chrome/browser/search/instant_service_factory.h" |
19 #include "chrome/browser/search_engines/template_url_service.h" | 20 #include "chrome/browser/search_engines/template_url_service.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 // Field trial groups should be named things like "Group7 espv:2 instant:1". | 52 // Field trial groups should be named things like "Group7 espv:2 instant:1". |
52 // The first token is always GroupN for some integer N, followed by a | 53 // The first token is always GroupN for some integer N, followed by a |
53 // space-delimited list of key:value pairs which correspond to these flags: | 54 // space-delimited list of key:value pairs which correspond to these flags: |
54 const char kEmbeddedPageVersionFlagName[] = "espv"; | 55 const char kEmbeddedPageVersionFlagName[] = "espv"; |
55 #if defined(OS_IOS) || defined(OS_ANDROID) | 56 #if defined(OS_IOS) || defined(OS_ANDROID) |
56 const uint64 kEmbeddedPageVersionDefault = 1; | 57 const uint64 kEmbeddedPageVersionDefault = 1; |
57 #else | 58 #else |
58 const uint64 kEmbeddedPageVersionDefault = 2; | 59 const uint64 kEmbeddedPageVersionDefault = 2; |
59 #endif | 60 #endif |
60 | 61 |
| 62 // The staleness timeout can be set (in seconds) via this config. |
| 63 const char kStalePageTimeoutFlagName[] = "stale"; |
| 64 const int kStalePageTimeoutDefault = 3 * 3600; // 3 hours. |
| 65 |
61 const char kHideVerbatimFlagName[] = "hide_verbatim"; | 66 const char kHideVerbatimFlagName[] = "hide_verbatim"; |
| 67 const char kShowNtpFlagName[] = "show_ntp"; |
| 68 const char kUseCacheableNTP[] = "use_cacheable_ntp"; |
62 const char kPrefetchSearchResultsFlagName[] = "prefetch_results"; | 69 const char kPrefetchSearchResultsFlagName[] = "prefetch_results"; |
63 const char kPrefetchSearchResultsOnSRP[] = "prefetch_results_srp"; | 70 const char kPrefetchSearchResultsOnSRP[] = "prefetch_results_srp"; |
64 const char kDisplaySearchButtonFlagName[] = "display_search_button"; | 71 const char kDisplaySearchButtonFlagName[] = "display_search_button"; |
65 const char kOriginChipFlagName[] = "origin_chip"; | 72 const char kOriginChipFlagName[] = "origin_chip"; |
66 #if !defined(OS_IOS) && !defined(OS_ANDROID) | 73 #if !defined(OS_IOS) && !defined(OS_ANDROID) |
67 const char kEnableQueryExtractionFlagName[] = "query_extraction"; | 74 const char kEnableQueryExtractionFlagName[] = "query_extraction"; |
68 #endif | 75 #endif |
69 | 76 |
70 // Constants for the field trial name and group prefix. | 77 // Constants for the field trial name and group prefix. |
71 // Note in M30 and below this field trial was named "InstantExtended" and in | 78 // Note in M30 and below this field trial was named "InstantExtended" and in |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 if (!contents || !entry || !IsInstantExtendedAPIEnabled()) | 388 if (!contents || !entry || !IsInstantExtendedAPIEnabled()) |
382 return false; | 389 return false; |
383 | 390 |
384 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | 391 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
385 if (!IsRenderedInInstantProcess(contents, profile)) | 392 if (!IsRenderedInInstantProcess(contents, profile)) |
386 return false; | 393 return false; |
387 | 394 |
388 if (entry->GetURL() == GetLocalInstantURL(profile)) | 395 if (entry->GetURL() == GetLocalInstantURL(profile)) |
389 return true; | 396 return true; |
390 | 397 |
391 GURL new_tab_url(GetNewTabPageURL(profile)); | 398 if (ShouldUseCacheableNTP()) { |
392 return new_tab_url.is_valid() && | 399 GURL new_tab_url(GetNewTabPageURL(profile)); |
393 search::MatchesOriginAndPath(entry->GetURL(), new_tab_url); | 400 return new_tab_url.is_valid() && |
| 401 search::MatchesOriginAndPath(entry->GetURL(), new_tab_url); |
| 402 } |
| 403 |
| 404 return IsInstantURL(entry->GetVirtualURL(), profile) && |
| 405 GetSearchTermsImpl(contents, entry).empty(); |
394 } | 406 } |
395 | 407 |
396 bool IsSuggestPrefEnabled(Profile* profile) { | 408 bool IsSuggestPrefEnabled(Profile* profile) { |
397 return profile && !profile->IsOffTheRecord() && profile->GetPrefs() && | 409 return profile && !profile->IsOffTheRecord() && profile->GetPrefs() && |
398 profile->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled); | 410 profile->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled); |
399 } | 411 } |
400 | 412 |
401 GURL GetInstantURL(Profile* profile, int start_margin, | 413 GURL GetInstantURL(Profile* profile, int start_margin, |
402 bool force_instant_results) { | 414 bool force_instant_results) { |
403 if (!IsInstantExtendedAPIEnabled() || !IsSuggestPrefEnabled(profile)) | 415 if (!IsInstantExtendedAPIEnabled() || !IsSuggestPrefEnabled(profile)) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 return result; | 451 return result; |
440 for (size_t i = 0; i < template_url->URLCount(); ++i) { | 452 for (size_t i = 0; i < template_url->URLCount(); ++i) { |
441 TemplateURLRef ref(template_url, i); | 453 TemplateURLRef ref(template_url, i); |
442 result.push_back(TemplateURLRefToGURL(ref, kDisableStartMargin, false, | 454 result.push_back(TemplateURLRefToGURL(ref, kDisableStartMargin, false, |
443 false)); | 455 false)); |
444 } | 456 } |
445 return result; | 457 return result; |
446 } | 458 } |
447 | 459 |
448 GURL GetNewTabPageURL(Profile* profile) { | 460 GURL GetNewTabPageURL(Profile* profile) { |
| 461 if (!ShouldUseCacheableNTP()) |
| 462 return GURL(); |
| 463 |
449 if (!profile || profile->IsOffTheRecord()) | 464 if (!profile || profile->IsOffTheRecord()) |
450 return GURL(); | 465 return GURL(); |
451 | 466 |
452 if (!IsSuggestPrefEnabled(profile)) | 467 if (!IsSuggestPrefEnabled(profile)) |
453 return GURL(chrome::kChromeSearchLocalNtpUrl); | 468 return GURL(chrome::kChromeSearchLocalNtpUrl); |
454 | 469 |
455 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); | 470 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); |
456 if (!template_url) | 471 if (!template_url) |
457 return GURL(chrome::kChromeSearchLocalNtpUrl); | 472 return GURL(chrome::kChromeSearchLocalNtpUrl); |
458 | 473 |
459 GURL url(TemplateURLRefToGURL(template_url->new_tab_url_ref(), | 474 GURL url(TemplateURLRefToGURL(template_url->new_tab_url_ref(), |
460 kDisableStartMargin, false, false)); | 475 kDisableStartMargin, false, false)); |
461 if (!url.is_valid() || !url.SchemeIsSecure()) | 476 if (!url.is_valid() || !url.SchemeIsSecure()) |
462 return GURL(chrome::kChromeSearchLocalNtpUrl); | 477 return GURL(chrome::kChromeSearchLocalNtpUrl); |
463 | 478 |
464 if (!IsURLAllowedForSupervisedUser(url, profile)) | 479 if (!IsURLAllowedForSupervisedUser(url, profile)) |
465 return GURL(chrome::kChromeSearchLocalNtpUrl); | 480 return GURL(chrome::kChromeSearchLocalNtpUrl); |
466 | 481 |
467 return url; | 482 return url; |
468 } | 483 } |
469 | 484 |
470 GURL GetSearchResultPrefetchBaseURL(Profile* profile) { | 485 GURL GetSearchResultPrefetchBaseURL(Profile* profile) { |
471 return ShouldPrefetchSearchResults() ? | 486 return ShouldPrefetchSearchResults() ? |
472 GetInstantURL(profile, kDisableStartMargin, true) : GURL(); | 487 GetInstantURL(profile, kDisableStartMargin, true) : GURL(); |
473 } | 488 } |
474 | 489 |
475 bool ShouldPrefetchSearchResults() { | 490 bool ShouldPrefetchSearchResults() { |
| 491 if (!ShouldUseCacheableNTP()) |
| 492 return false; |
| 493 |
476 FieldTrialFlags flags; | 494 FieldTrialFlags flags; |
477 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( | 495 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( |
478 kPrefetchSearchResultsFlagName, false, flags); | 496 kPrefetchSearchResultsFlagName, false, flags); |
479 } | 497 } |
480 | 498 |
481 GURL GetLocalInstantURL(Profile* profile) { | 499 GURL GetLocalInstantURL(Profile* profile) { |
482 return GURL(chrome::kChromeSearchLocalNtpUrl); | 500 return GURL(chrome::kChromeSearchLocalNtpUrl); |
483 } | 501 } |
484 | 502 |
485 bool ShouldHideTopVerbatimMatch() { | 503 bool ShouldHideTopVerbatimMatch() { |
486 FieldTrialFlags flags; | 504 FieldTrialFlags flags; |
487 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( | 505 return GetFieldTrialInfo(&flags) && GetBoolValueForFlagWithDefault( |
488 kHideVerbatimFlagName, false, flags); | 506 kHideVerbatimFlagName, false, flags); |
489 } | 507 } |
490 | 508 |
| 509 bool ShouldUseCacheableNTP() { |
| 510 FieldTrialFlags flags; |
| 511 return !GetFieldTrialInfo(&flags) || GetBoolValueForFlagWithDefault( |
| 512 kUseCacheableNTP, true, flags); |
| 513 } |
| 514 |
| 515 bool ShouldShowInstantNTP() { |
| 516 // If using the cacheable NTP, load the NTP directly instead of preloading its |
| 517 // contents using InstantNTP. |
| 518 if (ShouldUseCacheableNTP()) |
| 519 return false; |
| 520 |
| 521 FieldTrialFlags flags; |
| 522 return !GetFieldTrialInfo(&flags) || |
| 523 GetBoolValueForFlagWithDefault(kShowNtpFlagName, true, flags); |
| 524 } |
| 525 |
491 DisplaySearchButtonConditions GetDisplaySearchButtonConditions() { | 526 DisplaySearchButtonConditions GetDisplaySearchButtonConditions() { |
492 const CommandLine* cl = CommandLine::ForCurrentProcess(); | 527 const CommandLine* cl = CommandLine::ForCurrentProcess(); |
493 if (cl->HasSwitch(switches::kDisableSearchButtonInOmnibox)) { | 528 if (cl->HasSwitch(switches::kDisableSearchButtonInOmnibox)) { |
494 return DISPLAY_SEARCH_BUTTON_NEVER; | 529 return DISPLAY_SEARCH_BUTTON_NEVER; |
495 } else if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxForStr)) { | 530 } else if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxForStr)) { |
496 return DISPLAY_SEARCH_BUTTON_FOR_STR; | 531 return DISPLAY_SEARCH_BUTTON_FOR_STR; |
497 } else if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxForStrOrIip)) { | 532 } else if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxForStrOrIip)) { |
498 return DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP; | 533 return DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP; |
499 } else if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxAlways)) { | 534 } else if (cl->HasSwitch(switches::kEnableSearchButtonInOmniboxAlways)) { |
500 return DISPLAY_SEARCH_BUTTON_ALWAYS; | 535 return DISPLAY_SEARCH_BUTTON_ALWAYS; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 search::MatchesOriginAndPath(url, instant_url)) { | 598 search::MatchesOriginAndPath(url, instant_url)) { |
564 replacements.SetHost(online_ntp_host.c_str(), | 599 replacements.SetHost(online_ntp_host.c_str(), |
565 url_parse::Component(0, online_ntp_host.length())); | 600 url_parse::Component(0, online_ntp_host.length())); |
566 } | 601 } |
567 } | 602 } |
568 | 603 |
569 effective_url = effective_url.ReplaceComponents(replacements); | 604 effective_url = effective_url.ReplaceComponents(replacements); |
570 return effective_url; | 605 return effective_url; |
571 } | 606 } |
572 | 607 |
| 608 int GetInstantLoaderStalenessTimeoutSec() { |
| 609 int timeout_sec = kStalePageTimeoutDefault; |
| 610 FieldTrialFlags flags; |
| 611 if (GetFieldTrialInfo(&flags)) { |
| 612 timeout_sec = GetUInt64ValueForFlagWithDefault(kStalePageTimeoutFlagName, |
| 613 kStalePageTimeoutDefault, |
| 614 flags); |
| 615 } |
| 616 |
| 617 // Require a minimum 5 minute timeout. |
| 618 if (timeout_sec < 0 || (timeout_sec > 0 && timeout_sec < 300)) |
| 619 timeout_sec = kStalePageTimeoutDefault; |
| 620 |
| 621 // Randomize by upto 15% either side. |
| 622 timeout_sec = base::RandInt(timeout_sec * 0.85, timeout_sec * 1.15); |
| 623 |
| 624 return timeout_sec; |
| 625 } |
| 626 |
| 627 bool IsPreloadedInstantExtendedNTP(const content::WebContents* contents) { |
| 628 if (!IsInstantExtendedAPIEnabled()) |
| 629 return false; |
| 630 |
| 631 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 632 if (!profile_manager) |
| 633 return false; // The profile manager can be NULL while testing. |
| 634 |
| 635 const std::vector<Profile*>& profiles = profile_manager->GetLoadedProfiles(); |
| 636 for (size_t i = 0; i < profiles.size(); ++i) { |
| 637 const InstantService* instant_service = |
| 638 InstantServiceFactory::GetForProfile(profiles[i]); |
| 639 if (instant_service && instant_service->GetNTPContents() == contents) |
| 640 return true; |
| 641 } |
| 642 return false; |
| 643 } |
| 644 |
573 bool HandleNewTabURLRewrite(GURL* url, | 645 bool HandleNewTabURLRewrite(GURL* url, |
574 content::BrowserContext* browser_context) { | 646 content::BrowserContext* browser_context) { |
575 if (!IsInstantExtendedAPIEnabled()) | 647 if (!IsInstantExtendedAPIEnabled()) |
576 return false; | 648 return false; |
577 | 649 |
578 if (!url->SchemeIs(chrome::kChromeUIScheme) || | 650 if (!url->SchemeIs(chrome::kChromeUIScheme) || |
579 url->host() != chrome::kChromeUINewTabHost) | 651 url->host() != chrome::kChromeUINewTabHost) |
580 return false; | 652 return false; |
581 | 653 |
582 Profile* profile = Profile::FromBrowserContext(browser_context); | 654 Profile* profile = Profile::FromBrowserContext(browser_context); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 | 761 |
690 // Given a FieldTrialFlags object, returns the boolean value of the provided | 762 // Given a FieldTrialFlags object, returns the boolean value of the provided |
691 // flag. | 763 // flag. |
692 bool GetBoolValueForFlagWithDefault(const std::string& flag, | 764 bool GetBoolValueForFlagWithDefault(const std::string& flag, |
693 bool default_value, | 765 bool default_value, |
694 const FieldTrialFlags& flags) { | 766 const FieldTrialFlags& flags) { |
695 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); | 767 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); |
696 } | 768 } |
697 | 769 |
698 } // namespace chrome | 770 } // namespace chrome |
OLD | NEW |