OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 #if defined(TOOLKIT_VIEWS) | 32 #if defined(TOOLKIT_VIEWS) |
33 #include "views/focus/focus_manager.h" | 33 #include "views/focus/focus_manager.h" |
34 #include "views/view.h" | 34 #include "views/view.h" |
35 #include "views/widget/widget.h" | 35 #include "views/widget/widget.h" |
36 #endif | 36 #endif |
37 | 37 |
38 InstantController::InstantController(Profile* profile, | 38 InstantController::InstantController(Profile* profile, |
39 InstantDelegate* delegate) | 39 InstantDelegate* delegate) |
40 : delegate_(delegate), | 40 : delegate_(delegate), |
41 tab_contents_(NULL), | 41 tab_contents_(NULL), |
42 is_active_(false), | |
43 is_displayable_(false), | 42 is_displayable_(false), |
| 43 is_out_of_date_(true), |
44 commit_on_mouse_up_(false), | 44 commit_on_mouse_up_(false), |
45 last_transition_type_(content::PAGE_TRANSITION_LINK), | 45 last_transition_type_(content::PAGE_TRANSITION_LINK), |
46 ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)) { | 46 ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)) { |
47 PrefService* service = profile->GetPrefs(); | 47 PrefService* service = profile->GetPrefs(); |
48 if (service && !InstantFieldTrial::IsExperimentGroup(profile)) { | 48 if (service && !InstantFieldTrial::IsExperimentGroup(profile)) { |
49 // kInstantEnabledOnce was added after instant, set it now to make sure it | 49 // kInstantEnabledOnce was added after instant, set it now to make sure it |
50 // is correctly set. | 50 // is correctly set. |
51 service->SetBoolean(prefs::kInstantEnabledOnce, true); | 51 service->SetBoolean(prefs::kInstantEnabledOnce, true); |
52 } | 52 } |
53 } | 53 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 string16* suggested_text) { | 155 string16* suggested_text) { |
156 suggested_text->clear(); | 156 suggested_text->clear(); |
157 | 157 |
158 tab_contents_ = tab_contents; | 158 tab_contents_ = tab_contents; |
159 commit_on_mouse_up_ = false; | 159 commit_on_mouse_up_ = false; |
160 last_transition_type_ = match.transition; | 160 last_transition_type_ = match.transition; |
161 last_url_ = match.destination_url; | 161 last_url_ = match.destination_url; |
162 last_user_text_ = user_text; | 162 last_user_text_ = user_text; |
163 | 163 |
164 if (!ShouldUseInstant(match)) { | 164 if (!ShouldUseInstant(match)) { |
165 DestroyPreviewContentsAndLeaveActive(); | 165 Hide(); |
166 return false; | 166 return false; |
167 } | 167 } |
168 | 168 |
169 const TemplateURL* template_url = match.template_url; | 169 const TemplateURL* template_url = match.template_url; |
170 DCHECK(template_url); // ShouldUseInstant returns false if no turl. | 170 DCHECK(template_url); // ShouldUseInstant returns false if no turl. |
171 if (!loader_.get()) | 171 if (!loader_.get()) |
172 loader_.reset(new InstantLoader(this, template_url->id())); | 172 loader_.reset(new InstantLoader(this, template_url->id())); |
173 is_active_ = true; | |
174 | 173 |
175 // In some rare cases (involving group policy), Instant can go from the field | 174 // In some rare cases (involving group policy), Instant can go from the field |
176 // trial to normal mode, with no intervening call to DestroyPreviewContents() | 175 // trial to normal mode, with no intervening call to DestroyPreviewContents() |
177 // This would leave the loader in a weird state, which would manifest if the | 176 // This would leave the loader in a weird state, which would manifest if the |
178 // user pressed <Enter> without calling Update(). TODO(sreeram): Handle it. | 177 // user pressed <Enter> without calling Update(). TODO(sreeram): Handle it. |
179 if (InstantFieldTrial::IsHiddenExperiment(tab_contents->profile())) { | 178 if (InstantFieldTrial::IsHiddenExperiment(tab_contents->profile())) { |
| 179 // For the HIDDEN field trial we process |user_text| at commit time, which |
| 180 // means we're never really out of date. |
| 181 is_out_of_date_ = false; |
180 loader_->MaybeLoadInstantURL(tab_contents, template_url); | 182 loader_->MaybeLoadInstantURL(tab_contents, template_url); |
181 return true; | 183 return true; |
182 } | 184 } |
183 | 185 |
184 UpdateLoader(template_url, match.destination_url, match.transition, user_text, | 186 UpdateLoader(template_url, match.destination_url, match.transition, user_text, |
185 verbatim, suggested_text); | 187 verbatim, suggested_text); |
186 | 188 |
187 NotificationService::current()->Notify( | 189 NotificationService::current()->Notify( |
188 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, | 190 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
189 Source<InstantController>(this), | 191 Source<InstantController>(this), |
(...skipping 11 matching lines...) Expand all Loading... |
201 if (loader_.get()) | 203 if (loader_.get()) |
202 loader_->SetOmniboxBounds(bounds); | 204 loader_->SetOmniboxBounds(bounds); |
203 } | 205 } |
204 | 206 |
205 void InstantController::DestroyPreviewContents() { | 207 void InstantController::DestroyPreviewContents() { |
206 if (!loader_.get()) { | 208 if (!loader_.get()) { |
207 // We're not showing anything, nothing to do. | 209 // We're not showing anything, nothing to do. |
208 return; | 210 return; |
209 } | 211 } |
210 | 212 |
211 // ReleasePreviewContents sets is_active_ to false, but we need to set it | |
212 // before notifying the delegate, otherwise if the delegate asks for the state | |
213 // we'll still be active. | |
214 is_active_ = false; | |
215 delegate_->HideInstant(); | 213 delegate_->HideInstant(); |
216 delete ReleasePreviewContents(INSTANT_COMMIT_DESTROY); | 214 delete ReleasePreviewContents(INSTANT_COMMIT_DESTROY); |
217 } | 215 } |
218 | 216 |
219 void InstantController::DestroyPreviewContentsAndLeaveActive() { | 217 void InstantController::Hide() { |
| 218 is_out_of_date_ = true; |
220 commit_on_mouse_up_ = false; | 219 commit_on_mouse_up_ = false; |
221 if (is_displayable_) { | 220 if (is_displayable_) { |
222 is_displayable_ = false; | 221 is_displayable_ = false; |
223 delegate_->HideInstant(); | 222 delegate_->HideInstant(); |
224 } | 223 } |
225 last_user_text_.clear(); | |
226 } | 224 } |
227 | 225 |
228 bool InstantController::IsCurrent() { | 226 bool InstantController::IsCurrent() { |
229 // TODO(mmenke): See if we can do something more intelligent in the | 227 // TODO(mmenke): See if we can do something more intelligent in the |
230 // navigation pending case. | 228 // navigation pending case. |
231 return is_displayable_ && !loader_->IsNavigationPending() && | 229 return is_displayable_ && !loader_->IsNavigationPending() && |
232 !loader_->needs_reload(); | 230 !loader_->needs_reload(); |
233 } | 231 } |
234 | 232 |
235 bool InstantController::PrepareForCommit() { | 233 bool InstantController::PrepareForCommit() { |
236 // If we are not in the HIDDEN field trial, return the status of the preview. | 234 // If we are not in the HIDDEN field trial, return the status of the preview. |
237 if (!InstantFieldTrial::IsHiddenExperiment(tab_contents_->profile())) | 235 if (!InstantFieldTrial::IsHiddenExperiment(tab_contents_->profile())) |
238 return IsCurrent(); | 236 return IsCurrent(); |
239 | 237 |
240 TemplateURLService* model = TemplateURLServiceFactory::GetForProfile( | 238 TemplateURLService* model = TemplateURLServiceFactory::GetForProfile( |
241 tab_contents_->profile()); | 239 tab_contents_->profile()); |
242 if (!model) | 240 if (!model) |
243 return false; | 241 return false; |
244 | 242 |
245 const TemplateURL* template_url = model->GetDefaultSearchProvider(); | 243 const TemplateURL* template_url = model->GetDefaultSearchProvider(); |
246 if (last_user_text_.empty() || | 244 if (is_out_of_date_ || |
247 !IsValidInstantTemplateURL(template_url) || | 245 !IsValidInstantTemplateURL(template_url) || |
248 !loader_.get() || | 246 !loader_.get() || |
249 loader_->template_url_id() != template_url->id() || | 247 loader_->template_url_id() != template_url->id() || |
250 loader_->IsNavigationPending() || | 248 loader_->IsNavigationPending() || |
251 loader_->is_determining_if_page_supports_instant()) { | 249 loader_->is_determining_if_page_supports_instant()) { |
252 return false; | 250 return false; |
253 } | 251 } |
254 | 252 |
255 // Ignore the suggested text, as we are about to commit the verbatim query. | 253 // Ignore the suggested text, as we are about to commit the verbatim query. |
256 string16 suggested_text; | 254 string16 suggested_text; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 loader_->MaybeLoadInstantURL(tab_contents, template_url); | 384 loader_->MaybeLoadInstantURL(tab_contents, template_url); |
387 } | 385 } |
388 | 386 |
389 TabContentsWrapper* InstantController::ReleasePreviewContents( | 387 TabContentsWrapper* InstantController::ReleasePreviewContents( |
390 InstantCommitType type) { | 388 InstantCommitType type) { |
391 if (!loader_.get()) | 389 if (!loader_.get()) |
392 return NULL; | 390 return NULL; |
393 | 391 |
394 TabContentsWrapper* tab = loader_->ReleasePreviewContents(type); | 392 TabContentsWrapper* tab = loader_->ReleasePreviewContents(type); |
395 ClearBlacklist(); | 393 ClearBlacklist(); |
396 is_active_ = false; | |
397 is_displayable_ = false; | 394 is_displayable_ = false; |
398 commit_on_mouse_up_ = false; | 395 commit_on_mouse_up_ = false; |
399 omnibox_bounds_ = gfx::Rect(); | 396 omnibox_bounds_ = gfx::Rect(); |
400 loader_.reset(); | 397 loader_.reset(); |
401 return tab; | 398 return tab; |
402 } | 399 } |
403 | 400 |
404 void InstantController::CompleteRelease(TabContentsWrapper* tab) { | 401 void InstantController::CompleteRelease(TabContentsWrapper* tab) { |
405 tab->blocked_content_tab_helper()->SetAllContentsBlocked(false); | 402 tab->blocked_content_tab_helper()->SetAllContentsBlocked(false); |
406 } | 403 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 UpdateIsDisplayable(); | 454 UpdateIsDisplayable(); |
458 } | 455 } |
459 | 456 |
460 void InstantController::SwappedTabContents(InstantLoader* loader) { | 457 void InstantController::SwappedTabContents(InstantLoader* loader) { |
461 if (is_displayable_) | 458 if (is_displayable_) |
462 delegate_->ShowInstant(loader->preview_contents()); | 459 delegate_->ShowInstant(loader->preview_contents()); |
463 } | 460 } |
464 | 461 |
465 void InstantController::UpdateIsDisplayable() { | 462 void InstantController::UpdateIsDisplayable() { |
466 bool displayable = | 463 bool displayable = |
467 (loader_.get() && loader_->ready() && loader_->http_status_ok()); | 464 (!is_out_of_date_ && loader_.get() && loader_->ready() && |
| 465 loader_->http_status_ok()); |
468 if (displayable == is_displayable_) | 466 if (displayable == is_displayable_) |
469 return; | 467 return; |
470 | 468 |
471 is_displayable_ = displayable; | 469 is_displayable_ = displayable; |
472 if (!is_displayable_) { | 470 if (!is_displayable_) { |
473 delegate_->HideInstant(); | 471 delegate_->HideInstant(); |
474 } else { | 472 } else { |
475 delegate_->ShowInstant(loader_->preview_contents()); | 473 delegate_->ShowInstant(loader_->preview_contents()); |
476 NotificationService::current()->Notify( | 474 NotificationService::current()->Notify( |
477 chrome::NOTIFICATION_INSTANT_CONTROLLER_SHOWN, | 475 chrome::NOTIFICATION_INSTANT_CONTROLLER_SHOWN, |
478 Source<InstantController>(this), | 476 Source<InstantController>(this), |
479 NotificationService::NoDetails()); | 477 NotificationService::NoDetails()); |
480 } | 478 } |
481 } | 479 } |
482 | 480 |
483 void InstantController::UpdateLoader(const TemplateURL* template_url, | 481 void InstantController::UpdateLoader(const TemplateURL* template_url, |
484 const GURL& url, | 482 const GURL& url, |
485 content::PageTransition transition_type, | 483 content::PageTransition transition_type, |
486 const string16& user_text, | 484 const string16& user_text, |
487 bool verbatim, | 485 bool verbatim, |
488 string16* suggested_text) { | 486 string16* suggested_text) { |
| 487 is_out_of_date_ = false; |
489 loader_->SetOmniboxBounds(omnibox_bounds_); | 488 loader_->SetOmniboxBounds(omnibox_bounds_); |
490 loader_->Update(tab_contents_, template_url, url, transition_type, user_text, | 489 loader_->Update(tab_contents_, template_url, url, transition_type, user_text, |
491 verbatim, suggested_text); | 490 verbatim, suggested_text); |
492 UpdateIsDisplayable(); | 491 UpdateIsDisplayable(); |
493 } | 492 } |
494 | 493 |
495 bool InstantController::ShouldUseInstant(const AutocompleteMatch& match) { | 494 bool InstantController::ShouldUseInstant(const AutocompleteMatch& match) { |
496 TemplateURLService* model = TemplateURLServiceFactory::GetForProfile( | 495 TemplateURLService* model = TemplateURLServiceFactory::GetForProfile( |
497 tab_contents_->profile()); | 496 tab_contents_->profile()); |
498 if (!model) | 497 if (!model) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 if (destroy_factory_.empty()) { | 537 if (destroy_factory_.empty()) { |
539 MessageLoop::current()->PostTask( | 538 MessageLoop::current()->PostTask( |
540 FROM_HERE, destroy_factory_.NewRunnableMethod( | 539 FROM_HERE, destroy_factory_.NewRunnableMethod( |
541 &InstantController::DestroyLoaders)); | 540 &InstantController::DestroyLoaders)); |
542 } | 541 } |
543 } | 542 } |
544 | 543 |
545 void InstantController::DestroyLoaders() { | 544 void InstantController::DestroyLoaders() { |
546 loaders_to_destroy_.reset(); | 545 loaders_to_destroy_.reset(); |
547 } | 546 } |
OLD | NEW |