OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/instant/instant_controller.h" | 5 #include "chrome/browser/instant/instant_controller.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "chrome/browser/autocomplete/autocomplete_match.h" | 10 #include "chrome/browser/autocomplete/autocomplete_match.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 | 45 |
46 // An artificial delay (in milliseconds) we introduce before telling the Instant | 46 // An artificial delay (in milliseconds) we introduce before telling the Instant |
47 // page about the new omnibox bounds, in cases where the bounds shrink. This is | 47 // page about the new omnibox bounds, in cases where the bounds shrink. This is |
48 // to avoid the page jumping up/down very fast in response to bounds changes. | 48 // to avoid the page jumping up/down very fast in response to bounds changes. |
49 const int kUpdateBoundsDelayMS = 1000; | 49 const int kUpdateBoundsDelayMS = 1000; |
50 | 50 |
51 // The maximum number of times we'll load a non-Instant-supporting search engine | 51 // The maximum number of times we'll load a non-Instant-supporting search engine |
52 // before we give up and blacklist it for the rest of the browsing session. | 52 // before we give up and blacklist it for the rest of the browsing session. |
53 const int kMaxInstantSupportFailures = 10; | 53 const int kMaxInstantSupportFailures = 10; |
54 | 54 |
55 // If an instant page has not been used in this much time, it is reloaded so | |
56 // that the page does not become stale. | |
sreeram
2012/08/22 17:39:35
// If an Instant page has not been used in these m
Shishir
2012/08/23 18:26:33
Done.
| |
57 const int kInstantRefreshIntervalMS = 3 * 3600 * 1000; | |
sreeram
2012/08/22 17:39:35
Perhaps call this kStaleLoaderTimeoutMS?
Shishir
2012/08/23 18:26:33
Done.
| |
58 | |
55 std::string ModeToString(InstantController::Mode mode) { | 59 std::string ModeToString(InstantController::Mode mode) { |
56 switch (mode) { | 60 switch (mode) { |
57 case InstantController::INSTANT: return "_Instant"; | 61 case InstantController::INSTANT: return "_Instant"; |
58 case InstantController::SUGGEST: return "_Suggest"; | 62 case InstantController::SUGGEST: return "_Suggest"; |
59 case InstantController::HIDDEN: return "_Hidden"; | 63 case InstantController::HIDDEN: return "_Hidden"; |
60 case InstantController::SILENT: return "_Silent"; | 64 case InstantController::SILENT: return "_Silent"; |
61 } | 65 } |
62 | 66 |
63 NOTREACHED(); | 67 NOTREACHED(); |
64 return std::string(); | 68 return std::string(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 return false; | 165 return false; |
162 } | 166 } |
163 | 167 |
164 string16 full_text = user_text + *suggested_text; | 168 string16 full_text = user_text + *suggested_text; |
165 | 169 |
166 if (full_text.empty()) { | 170 if (full_text.empty()) { |
167 Hide(); | 171 Hide(); |
168 return false; | 172 return false; |
169 } | 173 } |
170 | 174 |
175 // Rechedule the instant loader refresh. | |
176 ScheduleLoaderRefresh(); | |
177 | |
171 // The presence of any suggested_text implies verbatim. | 178 // The presence of any suggested_text implies verbatim. |
172 DCHECK(suggested_text->empty() || verbatim) | 179 DCHECK(suggested_text->empty() || verbatim) |
173 << user_text << "|" << *suggested_text; | 180 << user_text << "|" << *suggested_text; |
174 | 181 |
175 ResetLoader(instant_url, active_tab); | 182 ResetLoader(instant_url, active_tab); |
176 last_active_tab_ = active_tab; | 183 last_active_tab_ = active_tab; |
177 | 184 |
178 // Track the non-Instant search URL for this query. | 185 // Track the non-Instant search URL for this query. |
179 url_for_history_ = match.destination_url; | 186 url_for_history_ = match.destination_url; |
180 last_transition_type_ = match.transition; | 187 last_transition_type_ = match.transition; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant(); | 264 return !IsOutOfDate() && GetPreviewContents() && loader_->supports_instant(); |
258 } | 265 } |
259 | 266 |
260 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) { | 267 TabContents* InstantController::CommitCurrentPreview(InstantCommitType type) { |
261 const TabContents* active_tab = delegate_->GetActiveTabContents(); | 268 const TabContents* active_tab = delegate_->GetActiveTabContents(); |
262 TabContents* preview = ReleasePreviewContents(type); | 269 TabContents* preview = ReleasePreviewContents(type); |
263 AddSessionStorageHistogram(mode_, active_tab, preview); | 270 AddSessionStorageHistogram(mode_, active_tab, preview); |
264 preview->web_contents()->GetController().CopyStateFromAndPrune( | 271 preview->web_contents()->GetController().CopyStateFromAndPrune( |
265 &active_tab->web_contents()->GetController()); | 272 &active_tab->web_contents()->GetController()); |
266 delegate_->CommitInstant(preview); | 273 delegate_->CommitInstant(preview); |
274 | |
275 // Try to create another loader immediately so that it is ready for the next | |
276 // user interaction. | |
277 ResetLoaderWithDefaultUrlAndCurrentTab(); | |
278 | |
267 return preview; | 279 return preview; |
268 } | 280 } |
269 | 281 |
270 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) { | 282 TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) { |
271 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); | 283 TabContents* preview = loader_->ReleasePreviewContents(type, last_full_text_); |
272 | 284 |
273 // If the preview page has navigated since the last Update(), we need to add | 285 // If the preview page has navigated since the last Update(), we need to add |
274 // the navigation to history ourselves. Else, the page will navigate after | 286 // the navigation to history ourselves. Else, the page will navigate after |
275 // commit, and it will be added to history in the usual manner. | 287 // commit, and it will be added to history in the usual manner. |
276 scoped_refptr<history::HistoryAddPageArgs> last_navigation = | 288 scoped_refptr<history::HistoryAddPageArgs> last_navigation = |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 if (view_gaining_focus_ancestor) { | 403 if (view_gaining_focus_ancestor) { |
392 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); | 404 CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); |
393 return; | 405 return; |
394 } | 406 } |
395 | 407 |
396 Hide(); | 408 Hide(); |
397 #endif | 409 #endif |
398 } | 410 } |
399 | 411 |
400 void InstantController::OnAutocompleteGotFocus() { | 412 void InstantController::OnAutocompleteGotFocus() { |
401 const TabContents* active_tab = delegate_->GetActiveTabContents(); | 413 ResetLoaderWithDefaultUrlAndCurrentTab(); |
402 | |
403 // We could get here with no active tab if the Browser is closing. | |
404 if (!active_tab) | |
405 return; | |
406 | |
407 // Since we don't have any autocomplete match to work with, we'll just use | |
408 // the default search provider's Instant URL. | |
409 const TemplateURL* template_url = | |
410 TemplateURLServiceFactory::GetForProfile(active_tab->profile())-> | |
411 GetDefaultSearchProvider(); | |
412 | |
413 std::string instant_url; | |
414 if (!GetInstantURL(template_url, &instant_url)) | |
415 return; | |
416 | |
417 ResetLoader(instant_url, active_tab); | |
418 } | 414 } |
419 | 415 |
420 bool InstantController::commit_on_pointer_release() const { | 416 bool InstantController::commit_on_pointer_release() const { |
421 return GetPreviewContents() && loader_->IsPointerDownFromActivate(); | 417 return GetPreviewContents() && loader_->IsPointerDownFromActivate(); |
422 } | 418 } |
423 | 419 |
424 void InstantController::SetSuggestions( | 420 void InstantController::SetSuggestions( |
425 InstantLoader* loader, | 421 InstantLoader* loader, |
426 const std::vector<InstantSuggestion>& suggestions) { | 422 const std::vector<InstantSuggestion>& suggestions) { |
427 DCHECK_EQ(loader_.get(), loader); | 423 DCHECK_EQ(loader_.get(), loader); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 DCHECK_EQ(loader_.get(), loader); | 495 DCHECK_EQ(loader_.get(), loader); |
500 DCHECK(is_showing_ && !IsOutOfDate()) << is_showing_; | 496 DCHECK(is_showing_ && !IsOutOfDate()) << is_showing_; |
501 #if defined(USE_AURA) | 497 #if defined(USE_AURA) |
502 // On aura the omnibox only receives a focus lost if we initiate the focus | 498 // On aura the omnibox only receives a focus lost if we initiate the focus |
503 // change. This does that. | 499 // change. This does that. |
504 if (is_showing_ && !IsOutOfDate()) | 500 if (is_showing_ && !IsOutOfDate()) |
505 delegate_->InstantPreviewFocused(); | 501 delegate_->InstantPreviewFocused(); |
506 #endif | 502 #endif |
507 } | 503 } |
508 | 504 |
505 void InstantController::CreateLoader(const std::string& instant_url, | |
506 const TabContents* active_tab) { | |
507 DCHECK(!loader_.get()); | |
508 loader_.reset(new InstantLoader(this, instant_url, active_tab)); | |
509 loader_->Init(); | |
510 ScheduleLoaderRefresh(); | |
511 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); | |
512 } | |
sreeram
2012/08/22 17:39:35
We don't need this method (CreateLoader) at all. W
Shishir
2012/08/23 18:26:33
Done.
| |
513 | |
509 void InstantController::ResetLoader(const std::string& instant_url, | 514 void InstantController::ResetLoader(const std::string& instant_url, |
510 const TabContents* active_tab) { | 515 const TabContents* active_tab) { |
511 if (GetPreviewContents() && loader_->instant_url() != instant_url) | 516 if (GetPreviewContents() && loader_->instant_url() != instant_url) |
512 DeleteLoader(); | 517 DeleteLoader(); |
513 | 518 |
514 if (!GetPreviewContents()) { | 519 if (!GetPreviewContents()) |
515 loader_.reset(new InstantLoader(this, instant_url, active_tab)); | 520 CreateLoader(instant_url, active_tab); |
516 loader_->Init(); | 521 } |
517 AddPreviewUsageForHistogram(mode_, PREVIEW_CREATED); | 522 |
523 void InstantController::ResetLoaderWithDefaultUrlAndCurrentTab() { | |
524 const TabContents* active_tab = delegate_->GetActiveTabContents(); | |
525 | |
526 // We could get here with no active tab if the Browser is closing. | |
527 if (!active_tab) | |
528 return; | |
529 | |
530 const TemplateURL* template_url = | |
531 TemplateURLServiceFactory::GetForProfile(active_tab->profile())-> | |
532 GetDefaultSearchProvider(); | |
533 std::string instant_url; | |
534 if (!GetInstantURL(template_url, &instant_url)) | |
535 return; | |
536 | |
537 ResetLoader(instant_url, active_tab); | |
538 } | |
539 | |
540 void InstantController::ScheduleLoaderRefresh() { | |
541 if (loader_refresh_timer_.IsRunning()) { | |
542 loader_refresh_timer_.Reset(); | |
543 } else { | |
544 loader_refresh_timer_.Start( | |
545 FROM_HERE, | |
546 base::TimeDelta::FromMilliseconds(kInstantRefreshIntervalMS), this, | |
547 &InstantController::RefreshLoader); | |
518 } | 548 } |
519 } | 549 } |
520 | 550 |
551 void InstantController::RefreshLoader() { | |
552 // If the loader is showing, do not delete it, but reschedule a refresh. | |
553 if (is_showing_) { | |
554 ScheduleLoaderRefresh(); | |
555 return; | |
556 } | |
557 | |
558 DeleteLoader(); | |
559 ResetLoaderWithDefaultUrlAndCurrentTab(); | |
560 } | |
561 | |
521 void InstantController::DeleteLoader() { | 562 void InstantController::DeleteLoader() { |
522 Hide(); | 563 Hide(); |
523 last_full_text_.clear(); | 564 last_full_text_.clear(); |
524 last_user_text_.clear(); | 565 last_user_text_.clear(); |
525 last_verbatim_ = false; | 566 last_verbatim_ = false; |
526 last_suggestion_ = InstantSuggestion(); | 567 last_suggestion_ = InstantSuggestion(); |
527 last_transition_type_ = content::PAGE_TRANSITION_LINK; | 568 last_transition_type_ = content::PAGE_TRANSITION_LINK; |
528 last_omnibox_bounds_ = gfx::Rect(); | 569 last_omnibox_bounds_ = gfx::Rect(); |
529 url_for_history_ = GURL(); | 570 url_for_history_ = GURL(); |
530 if (GetPreviewContents()) | 571 if (GetPreviewContents()) |
531 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED); | 572 AddPreviewUsageForHistogram(mode_, PREVIEW_DELETED); |
573 loader_refresh_timer_.Stop(); | |
532 loader_.reset(); | 574 loader_.reset(); |
533 } | 575 } |
534 | 576 |
535 void InstantController::Show() { | 577 void InstantController::Show() { |
536 if (!is_showing_) { | 578 if (!is_showing_) { |
537 is_showing_ = true; | 579 is_showing_ = true; |
538 delegate_->ShowInstant(); | 580 delegate_->ShowInstant(); |
539 AddPreviewUsageForHistogram(mode_, PREVIEW_SHOWED); | 581 AddPreviewUsageForHistogram(mode_, PREVIEW_SHOWED); |
540 } | 582 } |
541 } | 583 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
594 return false; | 636 return false; |
595 } | 637 } |
596 | 638 |
597 return true; | 639 return true; |
598 } | 640 } |
599 | 641 |
600 bool InstantController::IsOutOfDate() const { | 642 bool InstantController::IsOutOfDate() const { |
601 return !last_active_tab_ || | 643 return !last_active_tab_ || |
602 last_active_tab_ != delegate_->GetActiveTabContents(); | 644 last_active_tab_ != delegate_->GetActiveTabContents(); |
603 } | 645 } |
OLD | NEW |