| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 static const int kUpdateDelayMS = 200; | 31 static const int kUpdateDelayMS = 200; |
| 32 | 32 |
| 33 // static | 33 // static |
| 34 InstantController::HostBlacklist* InstantController::host_blacklist_ = NULL; | 34 InstantController::HostBlacklist* InstantController::host_blacklist_ = NULL; |
| 35 | 35 |
| 36 InstantController::InstantController(Profile* profile, | 36 InstantController::InstantController(Profile* profile, |
| 37 InstantDelegate* delegate) | 37 InstantDelegate* delegate) |
| 38 : delegate_(delegate), | 38 : delegate_(delegate), |
| 39 tab_contents_(NULL), | 39 tab_contents_(NULL), |
| 40 is_active_(false), | 40 is_active_(false), |
| 41 is_displayable_(false), |
| 41 commit_on_mouse_up_(false), | 42 commit_on_mouse_up_(false), |
| 42 last_transition_type_(PageTransition::LINK), | 43 last_transition_type_(PageTransition::LINK), |
| 43 ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)), | 44 ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)), |
| 44 type_(FIRST_TYPE) { | 45 type_(FIRST_TYPE) { |
| 45 bool enabled = GetType(profile, &type_); | 46 bool enabled = GetType(profile, &type_); |
| 46 DCHECK(enabled); | 47 DCHECK(enabled); |
| 47 PrefService* service = profile->GetPrefs(); | 48 PrefService* service = profile->GetPrefs(); |
| 48 if (service) { | 49 if (service) { |
| 49 // kInstantWasEnabledOnce was added after instant, set it now to make sure | 50 // kInstantWasEnabledOnce was added after instant, set it now to make sure |
| 50 // it is correctly set. | 51 // it is correctly set. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 | 150 |
| 150 if (tab_contents != tab_contents_) | 151 if (tab_contents != tab_contents_) |
| 151 DestroyPreviewContents(); | 152 DestroyPreviewContents(); |
| 152 | 153 |
| 153 const GURL& url = match.destination_url; | 154 const GURL& url = match.destination_url; |
| 154 tab_contents_ = tab_contents; | 155 tab_contents_ = tab_contents; |
| 155 commit_on_mouse_up_ = false; | 156 commit_on_mouse_up_ = false; |
| 156 last_transition_type_ = match.transition; | 157 last_transition_type_ = match.transition; |
| 157 const TemplateURL* template_url = NULL; | 158 const TemplateURL* template_url = NULL; |
| 158 | 159 |
| 159 if (url.is_empty() || !url.is_valid() || | 160 if (url.is_empty() || !url.is_valid()) { |
| 160 !ShouldShowPreviewFor(match, &template_url)) { | 161 // Assume we were invoked with GURL() and should destroy all. |
| 161 DestroyPreviewContents(); | 162 DestroyPreviewContents(); |
| 162 return; | 163 return; |
| 163 } | 164 } |
| 164 | 165 |
| 166 if (!ShouldShowPreviewFor(match, &template_url)) { |
| 167 DestroyAndLeaveActive(); |
| 168 return; |
| 169 } |
| 170 |
| 165 if (!loader_manager_.get()) | 171 if (!loader_manager_.get()) |
| 166 loader_manager_.reset(new InstantLoaderManager(this)); | 172 loader_manager_.reset(new InstantLoaderManager(this)); |
| 167 | 173 |
| 168 if (!is_active_) | 174 if (!is_active_) { |
| 175 is_active_ = true; |
| 169 delegate_->PrepareForInstant(); | 176 delegate_->PrepareForInstant(); |
| 177 } |
| 170 | 178 |
| 171 TemplateURLID template_url_id = template_url ? template_url->id() : 0; | 179 TemplateURLID template_url_id = template_url ? template_url->id() : 0; |
| 172 // Verbatim only makes sense if the search engines supports instant. | 180 // Verbatim only makes sense if the search engines supports instant. |
| 173 bool real_verbatim = template_url_id ? verbatim : false; | 181 bool real_verbatim = template_url_id ? verbatim : false; |
| 174 | 182 |
| 175 if (ShouldUpdateNow(template_url_id, match.destination_url)) { | 183 if (ShouldUpdateNow(template_url_id, match.destination_url)) { |
| 176 UpdateLoader(template_url, match.destination_url, match.transition, | 184 UpdateLoader(template_url, match.destination_url, match.transition, |
| 177 user_text, real_verbatim, suggested_text); | 185 user_text, real_verbatim, suggested_text); |
| 178 } else { | 186 } else { |
| 179 ScheduleUpdate(match.destination_url); | 187 ScheduleUpdate(match.destination_url); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 199 loader_manager_->pending_loader()->SetOmniboxBounds(bounds); | 207 loader_manager_->pending_loader()->SetOmniboxBounds(bounds); |
| 200 } | 208 } |
| 201 } | 209 } |
| 202 | 210 |
| 203 void InstantController::DestroyPreviewContents() { | 211 void InstantController::DestroyPreviewContents() { |
| 204 if (!loader_manager_.get()) { | 212 if (!loader_manager_.get()) { |
| 205 // We're not showing anything, nothing to do. | 213 // We're not showing anything, nothing to do. |
| 206 return; | 214 return; |
| 207 } | 215 } |
| 208 | 216 |
| 217 // ReleasePreviewContents sets is_active_ to false, but we need to set it |
| 218 // beore notifying the delegate so. |
| 219 is_active_ = false; |
| 209 delegate_->HideInstant(); | 220 delegate_->HideInstant(); |
| 210 delete ReleasePreviewContents(INSTANT_COMMIT_DESTROY); | 221 delete ReleasePreviewContents(INSTANT_COMMIT_DESTROY); |
| 211 } | 222 } |
| 212 | 223 |
| 213 bool InstantController::IsCurrent() { | 224 bool InstantController::IsCurrent() { |
| 214 return loader_manager_.get() && loader_manager_->active_loader()->ready() && | 225 return loader_manager_.get() && loader_manager_->active_loader() && |
| 215 !update_timer_.IsRunning(); | 226 loader_manager_->active_loader()->ready() && !update_timer_.IsRunning(); |
| 216 } | 227 } |
| 217 | 228 |
| 218 void InstantController::CommitCurrentPreview(InstantCommitType type) { | 229 void InstantController::CommitCurrentPreview(InstantCommitType type) { |
| 219 DCHECK(loader_manager_.get()); | 230 DCHECK(loader_manager_.get()); |
| 220 DCHECK(loader_manager_->current_loader()); | 231 DCHECK(loader_manager_->current_loader()); |
| 221 TabContentsWrapper* tab = ReleasePreviewContents(type); | 232 TabContentsWrapper* tab = ReleasePreviewContents(type); |
| 222 delegate_->CommitInstant(tab); | 233 delegate_->CommitInstant(tab); |
| 223 CompleteRelease(tab->tab_contents()); | 234 CompleteRelease(tab->tab_contents()); |
| 224 } | 235 } |
| 225 | 236 |
| 226 void InstantController::SetCommitOnMouseUp() { | 237 void InstantController::SetCommitOnMouseUp() { |
| 227 commit_on_mouse_up_ = true; | 238 commit_on_mouse_up_ = true; |
| 228 } | 239 } |
| 229 | 240 |
| 230 bool InstantController::IsMouseDownFromActivate() { | 241 bool InstantController::IsMouseDownFromActivate() { |
| 231 DCHECK(loader_manager_.get()); | 242 DCHECK(loader_manager_.get()); |
| 232 DCHECK(loader_manager_->current_loader()); | 243 DCHECK(loader_manager_->current_loader()); |
| 233 return loader_manager_->current_loader()->IsMouseDownFromActivate(); | 244 return loader_manager_->current_loader()->IsMouseDownFromActivate(); |
| 234 } | 245 } |
| 235 | 246 |
| 236 void InstantController::OnAutocompleteLostFocus( | 247 void InstantController::OnAutocompleteLostFocus( |
| 237 gfx::NativeView view_gaining_focus) { | 248 gfx::NativeView view_gaining_focus) { |
| 238 if (!is_active() || !GetPreviewContents()) | 249 if (!is_active() || !GetPreviewContents()) { |
| 250 DestroyPreviewContents(); |
| 239 return; | 251 return; |
| 252 } |
| 240 | 253 |
| 241 RenderWidgetHostView* rwhv = | 254 RenderWidgetHostView* rwhv = |
| 242 GetPreviewContents()->tab_contents()->GetRenderWidgetHostView(); | 255 GetPreviewContents()->tab_contents()->GetRenderWidgetHostView(); |
| 243 if (!view_gaining_focus || !rwhv) { | 256 if (!view_gaining_focus || !rwhv) { |
| 244 DestroyPreviewContents(); | 257 DestroyPreviewContents(); |
| 245 return; | 258 return; |
| 246 } | 259 } |
| 247 | 260 |
| 248 gfx::NativeView tab_view = | 261 gfx::NativeView tab_view = |
| 249 GetPreviewContents()->tab_contents()->GetNativeView(); | 262 GetPreviewContents()->tab_contents()->GetNativeView(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 | 308 |
| 296 // Loader may be null if the url blacklisted instant. | 309 // Loader may be null if the url blacklisted instant. |
| 297 scoped_ptr<InstantLoader> loader; | 310 scoped_ptr<InstantLoader> loader; |
| 298 if (loader_manager_->current_loader()) | 311 if (loader_manager_->current_loader()) |
| 299 loader.reset(loader_manager_->ReleaseCurrentLoader()); | 312 loader.reset(loader_manager_->ReleaseCurrentLoader()); |
| 300 TabContentsWrapper* tab = loader.get() ? | 313 TabContentsWrapper* tab = loader.get() ? |
| 301 loader->ReleasePreviewContents(type) : NULL; | 314 loader->ReleasePreviewContents(type) : NULL; |
| 302 | 315 |
| 303 ClearBlacklist(); | 316 ClearBlacklist(); |
| 304 is_active_ = false; | 317 is_active_ = false; |
| 318 is_displayable_ = false; |
| 319 commit_on_mouse_up_ = false; |
| 305 omnibox_bounds_ = gfx::Rect(); | 320 omnibox_bounds_ = gfx::Rect(); |
| 306 commit_on_mouse_up_ = false; | 321 loader_manager_.reset(); |
| 307 loader_manager_.reset(NULL); | |
| 308 update_timer_.Stop(); | 322 update_timer_.Stop(); |
| 309 return tab; | 323 return tab; |
| 310 } | 324 } |
| 311 | 325 |
| 312 void InstantController::CompleteRelease(TabContents* tab) { | 326 void InstantController::CompleteRelease(TabContents* tab) { |
| 313 tab->SetAllContentsBlocked(false); | 327 tab->SetAllContentsBlocked(false); |
| 314 } | 328 } |
| 315 | 329 |
| 316 TabContentsWrapper* InstantController::GetPreviewContents() { | 330 TabContentsWrapper* InstantController::GetPreviewContents() { |
| 317 return loader_manager_.get() ? | 331 return loader_manager_.get() && loader_manager_->current_loader() ? |
| 318 loader_manager_->current_loader()->preview_contents() : NULL; | 332 loader_manager_->current_loader()->preview_contents() : NULL; |
| 319 } | 333 } |
| 320 | 334 |
| 321 bool InstantController::IsShowingInstant() { | 335 bool InstantController::IsShowingInstant() { |
| 322 return loader_manager_.get() && | 336 return loader_manager_.get() && loader_manager_->current_loader() && |
| 323 loader_manager_->current_loader()->is_showing_instant(); | 337 loader_manager_->current_loader()->is_showing_instant(); |
| 324 } | 338 } |
| 325 | 339 |
| 326 bool InstantController::MightSupportInstant() { | 340 bool InstantController::MightSupportInstant() { |
| 327 return loader_manager_.get() && | 341 return loader_manager_.get() && loader_manager_->active_loader() && |
| 328 loader_manager_->active_loader()->is_showing_instant(); | 342 loader_manager_->active_loader()->is_showing_instant(); |
| 329 } | 343 } |
| 330 | 344 |
| 331 void InstantController::ShowInstantLoader(InstantLoader* loader) { | 345 void InstantController::ShowInstantLoader(InstantLoader* loader) { |
| 332 DCHECK(loader_manager_.get()); | 346 DCHECK(loader_manager_.get()); |
| 333 if (loader_manager_->current_loader() == loader) { | 347 if (loader_manager_->current_loader() == loader) { |
| 334 is_active_ = true; | 348 is_displayable_ = true; |
| 335 delegate_->ShowInstant(loader->preview_contents()); | 349 delegate_->ShowInstant(loader->preview_contents()); |
| 336 } else if (loader_manager_->pending_loader() == loader) { | 350 } else if (loader_manager_->pending_loader() == loader) { |
| 337 scoped_ptr<InstantLoader> old_loader; | 351 scoped_ptr<InstantLoader> old_loader; |
| 338 loader_manager_->MakePendingCurrent(&old_loader); | 352 loader_manager_->MakePendingCurrent(&old_loader); |
| 339 delegate_->ShowInstant(loader->preview_contents()); | 353 delegate_->ShowInstant(loader->preview_contents()); |
| 340 } else { | 354 } else { |
| 341 // The loader supports instant but isn't active yet. Nothing to do. | 355 // The loader supports instant but isn't active yet. Nothing to do. |
| 342 } | 356 } |
| 343 | 357 |
| 344 NotificationService::current()->Notify( | 358 NotificationService::current()->Notify( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 370 // revert. | 384 // revert. |
| 371 DestroyPreviewContents(); | 385 DestroyPreviewContents(); |
| 372 } | 386 } |
| 373 } | 387 } |
| 374 | 388 |
| 375 void InstantController::InstantLoaderDoesntSupportInstant( | 389 void InstantController::InstantLoaderDoesntSupportInstant( |
| 376 InstantLoader* loader) { | 390 InstantLoader* loader) { |
| 377 DCHECK(!loader->ready()); // We better not be showing this loader. | 391 DCHECK(!loader->ready()); // We better not be showing this loader. |
| 378 DCHECK(loader->template_url_id()); | 392 DCHECK(loader->template_url_id()); |
| 379 | 393 |
| 380 VLOG(1) << " provider does not support instant"; | 394 VLOG(1) << "provider does not support instant"; |
| 381 | 395 |
| 382 // Don't attempt to use instant for this search engine again. | 396 // Don't attempt to use instant for this search engine again. |
| 383 BlacklistFromInstant(loader->template_url_id()); | 397 BlacklistFromInstant(loader->template_url_id()); |
| 384 | 398 |
| 385 if (loader_manager_->active_loader() == loader) { | 399 if (loader_manager_->active_loader() == loader) { |
| 386 // The loader is active, shut down instant. | 400 // The loader is active, hide all. |
| 387 DestroyPreviewContents(); | 401 DestroyAndLeaveActive(); |
| 388 } else { | 402 } else { |
| 389 if (loader_manager_->current_loader() == loader && is_active_) { | 403 if (loader_manager_->current_loader() == loader && is_displayable_) { |
| 390 // There is a pending loader and we're active. Hide the preview. When then | 404 // There is a pending loader and we're active. Hide the preview. When then |
| 391 // pending loader finishes loading we'll notify the delegate to show. | 405 // pending loader finishes loading we'll notify the delegate to show. |
| 392 DCHECK(loader_manager_->pending_loader()); | 406 DCHECK(loader_manager_->pending_loader()); |
| 393 is_active_ = false; | 407 is_displayable_ = false; |
| 394 delegate_->HideInstant(); | 408 delegate_->HideInstant(); |
| 395 } | 409 } |
| 396 loader_manager_->DestroyLoader(loader); | 410 loader_manager_->DestroyLoader(loader); |
| 397 } | 411 } |
| 398 } | 412 } |
| 399 | 413 |
| 400 void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) { | 414 void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) { |
| 401 std::string host = url.host(); | 415 std::string host = url.host(); |
| 402 if (host.empty()) | 416 if (host.empty()) |
| 403 return; | 417 return; |
| 404 | 418 |
| 405 if (!host_blacklist_) | 419 if (!host_blacklist_) |
| 406 host_blacklist_ = new HostBlacklist; | 420 host_blacklist_ = new HostBlacklist; |
| 407 host_blacklist_->insert(host); | 421 host_blacklist_->insert(host); |
| 408 | 422 |
| 409 if (!loader_manager_.get()) | 423 if (!loader_manager_.get()) |
| 410 return; | 424 return; |
| 411 | 425 |
| 412 // Because of the state of the stack we can't destroy the loader now. | 426 // Because of the state of the stack we can't destroy the loader now. |
| 413 ScheduleDestroy(loader); | 427 ScheduleDestroy(loader); |
| 414 | 428 |
| 415 loader_manager_->ReleaseLoader(loader); | 429 loader_manager_->ReleaseLoader(loader); |
| 416 if (is_active_ && | 430 if (is_displayable_ && |
| 417 (!loader_manager_->active_loader() || | 431 (!loader_manager_->active_loader() || |
| 418 !loader_manager_->current_loader()->ready())) { | 432 !loader_manager_->current_loader()->ready())) { |
| 419 // Hide instant. When the pending loader finishes loading we'll go active | 433 // Hide instant. When the pending loader finishes loading we'll go active |
| 420 // again. | 434 // again. |
| 421 is_active_ = false; | 435 is_displayable_ = false; |
| 422 delegate_->HideInstant(); | 436 delegate_->HideInstant(); |
| 423 } | 437 } |
| 424 } | 438 } |
| 425 | 439 |
| 440 void InstantController::DestroyAndLeaveActive() { |
| 441 is_displayable_ = false; |
| 442 commit_on_mouse_up_ = false; |
| 443 delegate_->HideInstant(); |
| 444 |
| 445 loader_manager_.reset(new InstantLoaderManager(this)); |
| 446 update_timer_.Stop(); |
| 447 } |
| 448 |
| 449 TabContentsWrapper* InstantController::GetPendingPreviewContents() { |
| 450 return loader_manager_.get() && loader_manager_->pending_loader() ? |
| 451 loader_manager_->pending_loader()->preview_contents() : NULL; |
| 452 } |
| 453 |
| 426 bool InstantController::ShouldUpdateNow(TemplateURLID instant_id, | 454 bool InstantController::ShouldUpdateNow(TemplateURLID instant_id, |
| 427 const GURL& url) { | 455 const GURL& url) { |
| 428 DCHECK(loader_manager_.get()); | 456 DCHECK(loader_manager_.get()); |
| 429 | 457 |
| 430 if (instant_id) { | 458 if (instant_id) { |
| 431 // Update sites that support instant immediately, they can do their own | 459 // Update sites that support instant immediately, they can do their own |
| 432 // throttling. | 460 // throttling. |
| 433 return true; | 461 return true; |
| 434 } | 462 } |
| 435 | 463 |
| 436 if (url.SchemeIsFile()) | 464 if (url.SchemeIsFile()) |
| 437 return true; // File urls should load quickly, so don't delay loading them. | 465 return true; // File urls should load quickly, so don't delay loading them. |
| 438 | 466 |
| 439 if (loader_manager_->WillUpateChangeActiveLoader(instant_id)) { | 467 if (loader_manager_->WillUpateChangeActiveLoader(instant_id)) { |
| 440 // If Update would change loaders, update now. This indicates transitioning | 468 // If Update would change loaders, update now. This indicates transitioning |
| 441 // from an instant to non-instant loader. | 469 // from an instant to non-instant loader. |
| 442 return true; | 470 return true; |
| 443 } | 471 } |
| 444 | 472 |
| 445 InstantLoader* active_loader = loader_manager_->active_loader(); | 473 InstantLoader* active_loader = loader_manager_->active_loader(); |
| 446 // WillUpateChangeActiveLoader should return true if no active loader, so | 474 // WillUpateChangeActiveLoader should return true if no active loader, so |
| 447 // we know there will be an active loader if we get here. | 475 // we know there will be an active loader if we get here. |
| 448 DCHECK(active_loader); | 476 DCHECK(active_loader); |
| 449 // Immediately update if the hosts differ, otherwise we'll delay the update. | 477 // Immediately update if the url is the same (which should result in nothing |
| 450 return active_loader->url().host() != url.host(); | 478 // happening) or the hosts differ, otherwise we'll delay the update. |
| 479 return (active_loader->url() == url) || |
| 480 (active_loader->url().host() != url.host()); |
| 451 } | 481 } |
| 452 | 482 |
| 453 void InstantController::ScheduleUpdate(const GURL& url) { | 483 void InstantController::ScheduleUpdate(const GURL& url) { |
| 454 scheduled_url_ = url; | 484 scheduled_url_ = url; |
| 455 | 485 |
| 456 if (update_timer_.IsRunning()) | 486 if (update_timer_.IsRunning()) |
| 457 update_timer_.Stop(); | 487 update_timer_.Stop(); |
| 458 update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdateDelayMS), | 488 update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdateDelayMS), |
| 459 this, &InstantController::ProcessScheduledUpdate); | 489 this, &InstantController::ProcessScheduledUpdate); |
| 460 } | 490 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 return "Predictive"; | 636 return "Predictive"; |
| 607 case VERBATIM_TYPE: | 637 case VERBATIM_TYPE: |
| 608 return "Verbatim"; | 638 return "Verbatim"; |
| 609 case PREDICTIVE_NO_AUTO_COMPLETE_TYPE: | 639 case PREDICTIVE_NO_AUTO_COMPLETE_TYPE: |
| 610 return "PredictiveNoAutoComplete"; | 640 return "PredictiveNoAutoComplete"; |
| 611 default: | 641 default: |
| 612 NOTREACHED(); | 642 NOTREACHED(); |
| 613 return std::string(); | 643 return std::string(); |
| 614 } | 644 } |
| 615 } | 645 } |
| OLD | NEW |