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

Side by Side Diff: chrome/browser/instant/instant_controller.cc

Issue 11824050: InstantExtended: Committed NTP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 7 years, 10 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 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/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/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/autocomplete/autocomplete_provider.h" 12 #include "chrome/browser/autocomplete/autocomplete_provider.h"
13 #include "chrome/browser/google/google_util.h" 13 #include "chrome/browser/google/google_util.h"
14 #include "chrome/browser/history/history_service.h" 14 #include "chrome/browser/history/history_service.h"
15 #include "chrome/browser/history/history_service_factory.h" 15 #include "chrome/browser/history/history_service_factory.h"
16 #include "chrome/browser/history/history_tab_helper.h" 16 #include "chrome/browser/history/history_tab_helper.h"
17 #include "chrome/browser/instant/instant_loader.h" 17 #include "chrome/browser/instant/instant_ntp.h"
18 #include "chrome/browser/instant/instant_overlay.h"
18 #include "chrome/browser/instant/instant_tab.h" 19 #include "chrome/browser/instant/instant_tab.h"
19 #include "chrome/browser/platform_util.h" 20 #include "chrome/browser/platform_util.h"
20 #include "chrome/browser/search_engines/template_url_service.h" 21 #include "chrome/browser/search_engines/template_url_service.h"
21 #include "chrome/browser/search_engines/template_url_service_factory.h" 22 #include "chrome/browser/search_engines/template_url_service_factory.h"
22 #include "chrome/browser/ui/browser_instant_controller.h" 23 #include "chrome/browser/ui/browser_instant_controller.h"
23 #include "chrome/browser/ui/search/search_tab_helper.h" 24 #include "chrome/browser/ui/search/search_tab_helper.h"
24 #include "chrome/common/chrome_notification_types.h" 25 #include "chrome/common/chrome_notification_types.h"
25 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/url_constants.h"
26 #include "content/public/browser/navigation_entry.h" 28 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/render_widget_host_view.h" 30 #include "content/public/browser/render_widget_host_view.h"
29 #include "content/public/browser/web_contents.h" 31 #include "content/public/browser/web_contents.h"
30 #include "net/base/escape.h" 32 #include "net/base/escape.h"
31 #include "third_party/icu/public/common/unicode/normalizer2.h" 33 #include "third_party/icu/public/common/unicode/normalizer2.h"
32 34
33 #if defined(TOOLKIT_VIEWS) 35 #if defined(TOOLKIT_VIEWS)
34 #include "ui/views/widget/widget.h" 36 #include "ui/views/widget/widget.h"
35 #endif 37 #endif
36 38
37 namespace { 39 namespace {
38 40
39 // An artificial delay (in milliseconds) we introduce before telling the Instant 41 // An artificial delay (in milliseconds) we introduce before telling the Instant
40 // page about the new omnibox bounds, in cases where the bounds shrink. This is 42 // page about the new omnibox bounds, in cases where the bounds shrink. This is
41 // to avoid the page jumping up/down very fast in response to bounds changes. 43 // to avoid the page jumping up/down very fast in response to bounds changes.
42 const int kUpdateBoundsDelayMS = 1000; 44 const int kUpdateBoundsDelayMS = 1000;
43 45
44 // The maximum number of times we'll load a non-Instant-supporting search engine 46 // The maximum number of times we'll load a non-Instant-supporting search engine
45 // before we give up and blacklist it for the rest of the browsing session. 47 // before we give up and blacklist it for the rest of the browsing session.
46 const int kMaxInstantSupportFailures = 10; 48 const int kMaxInstantSupportFailures = 10;
47 49
48 // If an Instant page has not been used in these many milliseconds, it is
49 // reloaded so that the page does not become stale.
50 const int kStaleLoaderTimeoutMS = 3 * 3600 * 1000;
51
52 // For reporting events of interest. 50 // For reporting events of interest.
53 enum InstantControllerEvent { 51 enum InstantControllerEvent {
54 INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST = 0, 52 INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST = 0,
55 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST = 1, 53 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST = 1,
56 INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST = 2, 54 INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST = 2,
57 INSTANT_CONTROLLER_EVENT_MAX = 3, 55 INSTANT_CONTROLLER_EVENT_MAX = 3,
58 }; 56 };
59 57
60 void RecordEventHistogram(InstantControllerEvent event) { 58 void RecordEventHistogram(InstantControllerEvent event) {
61 UMA_HISTOGRAM_ENUMERATION("Instant.InstantControllerEvent", 59 UMA_HISTOGRAM_ENUMERATION("Instant.InstantControllerEvent",
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 return true; 151 return true;
154 } 152 }
155 153
156 return false; 154 return false;
157 } 155 }
158 156
159 bool IsFullHeight(const InstantModel& model) { 157 bool IsFullHeight(const InstantModel& model) {
160 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT; 158 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT;
161 } 159 }
162 160
161 bool IsContentsFrom(const InstantPage* page,
162 const content::WebContents* contents) {
163 return page && (page->contents() == contents);
164 }
165
163 } // namespace 166 } // namespace
164 167
165 // static 168 // static
166 const char* InstantController::kLocalOmniboxPopupURL = 169 const char* InstantController::kLocalOmniboxPopupURL =
167 "chrome://local-omnibox-popup/local-omnibox-popup.html"; 170 "chrome://local-omnibox-popup/local-omnibox-popup.html";
168 171
169 InstantController::InstantController(chrome::BrowserInstantController* browser, 172 InstantController::InstantController(chrome::BrowserInstantController* browser,
170 bool extended_enabled) 173 bool extended_enabled)
171 : browser_(browser), 174 : browser_(browser),
172 extended_enabled_(extended_enabled), 175 extended_enabled_(extended_enabled),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 is_keyword_search)); 213 is_keyword_search));
211 214
212 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions. 215 // TODO(dhollowa): Complete keyword match UI. For now just hide suggestions.
213 // http://crbug.com/153932. Note, this early escape is happens prior to the 216 // http://crbug.com/153932. Note, this early escape is happens prior to the
214 // DCHECKs below because |user_text| and |full_text| have different semantics 217 // DCHECKs below because |user_text| and |full_text| have different semantics
215 // when keyword search is in effect. 218 // when keyword search is in effect.
216 if (is_keyword_search) { 219 if (is_keyword_search) {
217 if (instant_tab_) 220 if (instant_tab_)
218 instant_tab_->Update(string16(), 0, 0, true); 221 instant_tab_->Update(string16(), 0, 0, true);
219 else 222 else
220 HideLoader(); 223 HideOverlay();
221 last_match_was_search_ = false; 224 last_match_was_search_ = false;
222 return false; 225 return false;
223 } 226 }
224 227
225 // If the popup is open, the user has to be typing. 228 // If the popup is open, the user has to be typing.
226 DCHECK(!omnibox_popup_is_open || user_input_in_progress); 229 DCHECK(!omnibox_popup_is_open || user_input_in_progress);
227 230
228 // If the popup is closed, there should be no inline autocompletion. 231 // If the popup is closed, there should be no inline autocompletion.
229 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text) 232 DCHECK(omnibox_popup_is_open || user_text.empty() || user_text == full_text)
230 << user_text << "|" << full_text; 233 << user_text << "|" << full_text;
231 234
232 // If there's no text in the omnibox, the user can't have typed any. 235 // If there's no text in the omnibox, the user can't have typed any.
233 DCHECK(!full_text.empty() || user_text.empty()) << user_text; 236 DCHECK(!full_text.empty() || user_text.empty()) << user_text;
234 237
235 // If the user isn't typing, and the popup is closed, there can't be any 238 // If the user isn't typing, and the popup is closed, there can't be any
236 // user-typed text. 239 // user-typed text.
237 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty()) 240 DCHECK(user_input_in_progress || omnibox_popup_is_open || user_text.empty())
238 << user_text; 241 << user_text;
239 242
240 // The preview is being clicked and will commit soon. Don't change anything. 243 // The preview is being clicked and will commit soon. Don't change anything.
241 // TODO(sreeram): Add a browser test for this. 244 // TODO(sreeram): Add a browser test for this.
242 if (loader_ && loader_->is_pointer_down_from_activate()) 245 if (overlay_ && overlay_->is_pointer_down_from_activate())
243 return false; 246 return false;
244 247
245 // In non-extended mode, SearchModeChanged() is never called, so fake it. The 248 // In non-extended mode, SearchModeChanged() is never called, so fake it. The
246 // mode is set to "disallow suggestions" here, so that if one of the early 249 // mode is set to "disallow suggestions" here, so that if one of the early
247 // "return false" conditions is hit, suggestions will be disallowed. If the 250 // "return false" conditions is hit, suggestions will be disallowed. If the
248 // query is sent to the loader, the mode is set to "allow" further below. 251 // query is sent to the overlay, the mode is set to "allow" further below.
249 if (!extended_enabled_) 252 if (!extended_enabled_)
250 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT; 253 search_mode_.mode = chrome::search::Mode::MODE_DEFAULT;
251 254
252 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) && 255 last_match_was_search_ = AutocompleteMatch::IsSearchType(match.type) &&
253 !user_text.empty(); 256 !user_text.empty();
254 257
255 // In non extended mode, Instant is disabled for URLs and keyword mode. 258 // In non extended mode, Instant is disabled for URLs and keyword mode.
256 if (!extended_enabled_ && 259 if (!extended_enabled_ &&
257 (!last_match_was_search_ || 260 (!last_match_was_search_ ||
258 match.type == AutocompleteMatch::SEARCH_OTHER_ENGINE)) { 261 match.type == AutocompleteMatch::SEARCH_OTHER_ENGINE)) {
259 HideLoader(); 262 HideOverlay();
260 return false; 263 return false;
261 } 264 }
262 265
263 // If we have an |instant_tab_| use it, else ensure we have a loader that is 266 // If we have an |instant_tab_| use it, else ensure we have a overlay that is
264 // current or is using local preview. 267 // current or is using local preview.
265 if (!instant_tab_ && !(loader_ && loader_->IsUsingLocalPreview()) && 268 if (!instant_tab_ && !(overlay_ && overlay_->IsUsingLocalPreview()) &&
266 !EnsureLoaderIsCurrent(false)) { 269 !EnsureOverlayIsCurrent(false)) {
267 HideLoader(); 270 HideOverlay();
268 return false; 271 return false;
269 } 272 }
270 273
271 if (extended_enabled_) { 274 if (extended_enabled_) {
272 if (!omnibox_popup_is_open) { 275 if (!omnibox_popup_is_open) {
273 if (!user_input_in_progress) { 276 if (!user_input_in_progress) {
274 // If the user isn't typing and the omnibox popup is closed, it means a 277 // If the user isn't typing and the omnibox popup is closed, it means a
275 // regular navigation, tab-switch or the user hitting Escape. 278 // regular navigation, tab-switch or the user hitting Escape.
276 if (instant_tab_) { 279 if (instant_tab_) {
277 // The user is on a search results page. It may be showing results for 280 // The user is on a search results page. It may be showing results for
278 // a partial query the user typed before they hit Escape. Send the 281 // a partial query the user typed before they hit Escape. Send the
279 // omnibox text to the page to restore the original results. 282 // omnibox text to the page to restore the original results.
280 // 283 //
281 // In a tab switch, |instant_tab_| won't have updated yet, so it may 284 // In a tab switch, |instant_tab_| won't have updated yet, so it may
282 // be pointing to the previous tab (which was a search results page). 285 // be pointing to the previous tab (which was a search results page).
283 // Ensure we don't send the omnibox text to a random webpage (the new 286 // Ensure we don't send the omnibox text to a random webpage (the new
284 // tab), by comparing the old and new WebContents. 287 // tab), by comparing the old and new WebContents.
285 if (escape_pressed && 288 if (escape_pressed &&
286 instant_tab_->contents() == browser_->GetActiveWebContents()) { 289 instant_tab_->contents() == browser_->GetActiveWebContents()) {
287 instant_tab_->Submit(full_text); 290 instant_tab_->Submit(full_text);
288 } 291 }
289 } else if (!full_text.empty()) { 292 } else if (!full_text.empty()) {
290 // If |full_text| is empty, the user is on the NTP. The preview may 293 // If |full_text| is empty, the user is on the NTP. The preview may
291 // be showing custom NTP content; hide only if that's not the case. 294 // be showing custom NTP content; hide only if that's not the case.
292 HideLoader(); 295 HideOverlay();
293 } 296 }
294 } else if (full_text.empty()) { 297 } else if (full_text.empty()) {
295 // The user is typing, and backspaced away all omnibox text. Clear 298 // The user is typing, and backspaced away all omnibox text. Clear
296 // |last_omnibox_text_| so that we don't attempt to set suggestions. 299 // |last_omnibox_text_| so that we don't attempt to set suggestions.
297 last_omnibox_text_.clear(); 300 last_omnibox_text_.clear();
298 last_suggestion_ = InstantSuggestion(); 301 last_suggestion_ = InstantSuggestion();
299 if (instant_tab_) { 302 if (instant_tab_) {
300 // On a search results page, tell it to clear old results. 303 // On a search results page, tell it to clear old results.
301 instant_tab_->Update(string16(), 0, 0, true); 304 instant_tab_->Update(string16(), 0, 0, true);
302 } else if (search_mode_.is_origin_ntp()) { 305 } else if (search_mode_.is_origin_ntp()) {
303 // On the NTP, tell the preview to clear old results. Don't hide the 306 // On the NTP, tell the preview to clear old results. Don't hide the
304 // preview so it can show a blank page or logo if it wants. 307 // preview so it can show a blank page or logo if it wants.
305 loader_->Update(string16(), 0, 0, true); 308 overlay_->Update(string16(), 0, 0, true);
306 } else { 309 } else {
307 HideLoader(); 310 HideOverlay();
308 } 311 }
309 } else { 312 } else {
310 // The user switched to a tab with partial text already in the omnibox. 313 // The user switched to a tab with partial text already in the omnibox.
311 HideLoader(); 314 HideOverlay();
312 315
313 // The new tab may or may not be a search results page; we don't know 316 // The new tab may or may not be a search results page; we don't know
314 // since SearchModeChanged() hasn't been called yet. If it later turns 317 // since SearchModeChanged() hasn't been called yet. If it later turns
315 // out to be, we should store |full_text| now, so that if the user hits 318 // out to be, we should store |full_text| now, so that if the user hits
316 // Enter, we'll send the correct query to instant_tab_->Submit(). If the 319 // Enter, we'll send the correct query to instant_tab_->Submit(). If the
317 // partial text is not a query (|last_match_was_search_| is false), we 320 // partial text is not a query (|last_match_was_search_| is false), we
318 // won't Submit(), so no need to worry about that. 321 // won't Submit(), so no need to worry about that.
319 last_omnibox_text_ = full_text; 322 last_omnibox_text_ = full_text;
320 last_suggestion_ = InstantSuggestion(); 323 last_suggestion_ = InstantSuggestion();
321 } 324 }
322 return false; 325 return false;
323 } else if (full_text.empty()) { 326 } else if (full_text.empty()) {
324 // The user typed a solitary "?". Same as the backspace case above. 327 // The user typed a solitary "?". Same as the backspace case above.
325 last_omnibox_text_.clear(); 328 last_omnibox_text_.clear();
326 last_suggestion_ = InstantSuggestion(); 329 last_suggestion_ = InstantSuggestion();
327 if (instant_tab_) 330 if (instant_tab_)
328 instant_tab_->Update(string16(), 0, 0, true); 331 instant_tab_->Update(string16(), 0, 0, true);
329 else if (search_mode_.is_origin_ntp()) 332 else if (search_mode_.is_origin_ntp())
330 loader_->Update(string16(), 0, 0, true); 333 overlay_->Update(string16(), 0, 0, true);
331 else 334 else
332 HideLoader(); 335 HideOverlay();
333 return false; 336 return false;
334 } 337 }
335 } else if (!omnibox_popup_is_open || full_text.empty()) { 338 } else if (!omnibox_popup_is_open || full_text.empty()) {
336 // In the non-extended case, hide the preview as long as the user isn't 339 // In the non-extended case, hide the preview as long as the user isn't
337 // actively typing a non-empty query. 340 // actively typing a non-empty query.
338 HideLoader(); 341 HideOverlay();
339 return false; 342 return false;
340 } 343 }
341 344
342 last_omnibox_text_has_inline_autocompletion_ = user_text != full_text; 345 last_omnibox_text_has_inline_autocompletion_ = user_text != full_text;
343 346
344 // If the user continues typing the same query as the suggested text is 347 // If the user continues typing the same query as the suggested text is
345 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER). 348 // showing, reuse the suggestion (but only for INSTANT_COMPLETE_NEVER).
346 bool reused_suggestion = false; 349 bool reused_suggestion = false;
347 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER && 350 if (last_suggestion_.behavior == INSTANT_COMPLETE_NEVER &&
348 !last_omnibox_text_has_inline_autocompletion_) { 351 !last_omnibox_text_has_inline_autocompletion_) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 383
381 if (instant_tab_) { 384 if (instant_tab_) {
382 instant_tab_->Update(user_text, selection_start, selection_end, verbatim); 385 instant_tab_->Update(user_text, selection_start, selection_end, verbatim);
383 } else { 386 } else {
384 if (first_interaction_time_.is_null()) 387 if (first_interaction_time_.is_null())
385 first_interaction_time_ = base::Time::Now(); 388 first_interaction_time_ = base::Time::Now();
386 allow_preview_to_show_search_suggestions_ = true; 389 allow_preview_to_show_search_suggestions_ = true;
387 390
388 // For extended mode, if the loader is not ready at this point, switch over 391 // For extended mode, if the loader is not ready at this point, switch over
389 // to a backup loader. 392 // to a backup loader.
390 if (extended_enabled_ && !loader_->supports_instant() && 393 if (extended_enabled_ && !overlay_->supports_instant() &&
391 !loader_->IsUsingLocalPreview() && browser_->GetActiveWebContents()) { 394 !overlay_->IsUsingLocalPreview() && browser_->GetActiveWebContents()) {
392 CreateLoader(kLocalOmniboxPopupURL, browser_->GetActiveWebContents()); 395 CreateOverlay(kLocalOmniboxPopupURL, browser_->GetActiveWebContents());
393 } 396 }
394 397
395 loader_->Update(extended_enabled_ ? user_text : full_text, 398 overlay_->Update(extended_enabled_ ? user_text : full_text,
396 selection_start, selection_end, verbatim); 399 selection_start, selection_end, verbatim);
397 } 400 }
398 401
399 content::NotificationService::current()->Notify( 402 content::NotificationService::current()->Notify(
400 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, 403 chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
401 content::Source<InstantController>(this), 404 content::Source<InstantController>(this),
402 content::NotificationService::NoDetails()); 405 content::NotificationService::NoDetails());
403 406
404 // We don't have new suggestions yet, but we can either reuse the existing 407 // We don't have new suggestions yet, but we can either reuse the existing
405 // suggestion or reset the existing "gray text". 408 // suggestion or reset the existing "gray text".
406 browser_->SetInstantSuggestion(last_suggestion_); 409 browser_->SetInstantSuggestion(last_suggestion_);
407 410
408 return true; 411 return true;
409 } 412 }
410 413
414 scoped_ptr<content::WebContents> InstantController::ReleaseNTPContents() {
415 if (!extended_enabled_ || !ntp_)
416 return scoped_ptr<content::WebContents>(NULL);
417
418 LOG_INSTANT_DEBUG_EVENT(this, "ReleaseNTPContents");
419
420 scoped_ptr<content::WebContents> ntp_contents = ntp_->ReleaseContents();
421 ntp_.reset();
422 ResetNTP();
423 return ntp_contents.Pass();
424 }
425
411 // TODO(tonyg): This method only fires when the omnibox bounds change. It also 426 // TODO(tonyg): This method only fires when the omnibox bounds change. It also
412 // needs to fire when the preview bounds change (e.g.: open/close info bar). 427 // needs to fire when the preview bounds change (e.g.: open/close info bar).
413 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { 428 void InstantController::SetPopupBounds(const gfx::Rect& bounds) {
414 if (!extended_enabled_ && !instant_enabled_) 429 if (!extended_enabled_ && !instant_enabled_)
415 return; 430 return;
416 431
417 if (popup_bounds_ == bounds) 432 if (popup_bounds_ == bounds)
418 return; 433 return;
419 434
420 popup_bounds_ = bounds; 435 popup_bounds_ = bounds;
421 if (popup_bounds_.height() > last_popup_bounds_.height()) { 436 if (popup_bounds_.height() > last_popup_bounds_.height()) {
422 update_bounds_timer_.Stop(); 437 update_bounds_timer_.Stop();
423 SendPopupBoundsToPage(); 438 SendPopupBoundsToPage();
424 } else if (!update_bounds_timer_.IsRunning()) { 439 } else if (!update_bounds_timer_.IsRunning()) {
425 update_bounds_timer_.Start(FROM_HERE, 440 update_bounds_timer_.Start(FROM_HERE,
426 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, 441 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this,
427 &InstantController::SendPopupBoundsToPage); 442 &InstantController::SendPopupBoundsToPage);
428 } 443 }
429 } 444 }
430 445
431 void InstantController::SetMarginSize(int start, int end) { 446 void InstantController::SetMarginSize(int start, int end) {
432 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end)) 447 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end))
433 return; 448 return;
434 449
435 start_margin_ = start; 450 start_margin_ = start;
436 end_margin_ = end; 451 end_margin_ = end;
437 if (loader_) 452 if (overlay_)
438 loader_->SetMarginSize(start_margin_, end_margin_); 453 overlay_->SetMarginSize(start_margin_, end_margin_);
454 if (ntp_)
455 ntp_->SetMarginSize(start_margin_, end_margin_);
439 if (instant_tab_) 456 if (instant_tab_)
440 instant_tab_->SetMarginSize(start_margin_, end_margin_); 457 instant_tab_->SetMarginSize(start_margin_, end_margin_);
441 } 458 }
442 459
443 void InstantController::HandleAutocompleteResults( 460 void InstantController::HandleAutocompleteResults(
444 const std::vector<AutocompleteProvider*>& providers) { 461 const std::vector<AutocompleteProvider*>& providers) {
445 if (!extended_enabled_) 462 if (!extended_enabled_)
446 return; 463 return;
447 464
448 if (!instant_tab_ && !loader_) 465 if (!instant_tab_ && !overlay_)
449 return; 466 return;
450 467
451 DVLOG(1) << "AutocompleteResults:"; 468 DVLOG(1) << "AutocompleteResults:";
452 std::vector<InstantAutocompleteResult> results; 469 std::vector<InstantAutocompleteResult> results;
453 for (ACProviders::const_iterator provider = providers.begin(); 470 for (ACProviders::const_iterator provider = providers.begin();
454 provider != providers.end(); ++provider) { 471 provider != providers.end(); ++provider) {
455 for (ACMatches::const_iterator match = (*provider)->matches().begin(); 472 for (ACMatches::const_iterator match = (*provider)->matches().begin();
456 match != (*provider)->matches().end(); ++match) { 473 match != (*provider)->matches().end(); ++match) {
457 InstantAutocompleteResult result; 474 InstantAutocompleteResult result;
458 result.provider = UTF8ToUTF16((*provider)->GetName()); 475 result.provider = UTF8ToUTF16((*provider)->GetName());
459 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); 476 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type));
460 result.description = match->description; 477 result.description = match->description;
461 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); 478 result.destination_url = UTF8ToUTF16(match->destination_url.spec());
462 result.transition = match->transition; 479 result.transition = match->transition;
463 result.relevance = match->relevance; 480 result.relevance = match->relevance;
464 DVLOG(1) << " " << result.relevance << " " << result.type << " " 481 DVLOG(1) << " " << result.relevance << " " << result.type << " "
465 << result.provider << " " << result.destination_url << " '" 482 << result.provider << " " << result.destination_url << " '"
466 << result.description << "' " << result.transition; 483 << result.description << "' " << result.transition;
467 results.push_back(result); 484 results.push_back(result);
468 } 485 }
469 } 486 }
470 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 487 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
471 "HandleAutocompleteResults: total_results=%d", 488 "HandleAutocompleteResults: total_results=%d",
472 static_cast<int>(results.size()))); 489 static_cast<int>(results.size())));
473 490
474 if (instant_tab_) 491 if (instant_tab_)
475 instant_tab_->SendAutocompleteResults(results); 492 instant_tab_->SendAutocompleteResults(results);
476 else 493 else
477 loader_->SendAutocompleteResults(results); 494 overlay_->SendAutocompleteResults(results);
478 } 495 }
479 496
480 bool InstantController::OnUpOrDownKeyPressed(int count) { 497 bool InstantController::OnUpOrDownKeyPressed(int count) {
481 if (!extended_enabled_) 498 if (!extended_enabled_)
482 return false; 499 return false;
483 500
484 if (!instant_tab_ && !loader_) 501 if (!instant_tab_ && !overlay_)
485 return false; 502 return false;
486 503
487 if (instant_tab_) 504 if (instant_tab_)
488 instant_tab_->UpOrDownKeyPressed(count); 505 instant_tab_->UpOrDownKeyPressed(count);
489 else 506 else
490 loader_->UpOrDownKeyPressed(count); 507 overlay_->UpOrDownKeyPressed(count);
491 508
492 return true; 509 return true;
493 } 510 }
494 511
495 content::WebContents* InstantController::GetPreviewContents() const { 512 content::WebContents* InstantController::GetPreviewContents() const {
496 return loader_ ? loader_->contents() : NULL; 513 return overlay_ ? overlay_->contents() : NULL;
497 } 514 }
498 515
499 bool InstantController::IsPreviewingSearchResults() const { 516 bool InstantController::IsPreviewingSearchResults() const {
500 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && 517 return model_.mode().is_search_suggestions() && IsFullHeight(model_) &&
501 (last_match_was_search_ || 518 (last_match_was_search_ ||
502 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); 519 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER);
503 } 520 }
504 521
505 bool InstantController::CommitIfPossible(InstantCommitType type) { 522 bool InstantController::CommitIfPossible(InstantCommitType type) {
506 if (!extended_enabled_ && !instant_enabled_) 523 if (!extended_enabled_ && !instant_enabled_)
(...skipping 16 matching lines...) Expand all
523 return true; 540 return true;
524 } 541 }
525 return false; 542 return false;
526 } 543 }
527 544
528 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) 545 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED)
529 return false; 546 return false;
530 547
531 // There may re-entrance here, from the call to browser_->CommitInstant below, 548 // There may re-entrance here, from the call to browser_->CommitInstant below,
532 // which can cause a TabDeactivated notification which gets back here. 549 // which can cause a TabDeactivated notification which gets back here.
533 // In this case, loader_->ReleaseContents() was called already. 550 // In this case, overlay_->ReleaseContents() was called already.
534 if (!GetPreviewContents()) 551 if (!GetPreviewContents())
535 return false; 552 return false;
536 553
537 // Never commit the local omnibox. 554 // Never commit the local omnibox.
538 if (loader_->IsUsingLocalPreview()) 555 if (overlay_->IsUsingLocalPreview())
539 return false; 556 return false;
540 557
541 if (type == INSTANT_COMMIT_FOCUS_LOST) 558 if (type == INSTANT_COMMIT_FOCUS_LOST)
542 loader_->Cancel(last_omnibox_text_); 559 overlay_->Cancel(last_omnibox_text_);
543 else if (type != INSTANT_COMMIT_NAVIGATED && 560 else if (type != INSTANT_COMMIT_NAVIGATED &&
544 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) 561 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION)
545 loader_->Submit(last_omnibox_text_); 562 overlay_->Submit(last_omnibox_text_);
546 563
547 content::WebContents* preview = loader_->ReleaseContents(); 564 scoped_ptr<content::WebContents> preview = overlay_->ReleaseContents();
548 565
549 if (extended_enabled_) { 566 if (extended_enabled_) {
550 // Consider what's happening: 567 // Consider what's happening:
551 // 1. The user has typed a query in the omnibox and committed it (either 568 // 1. The user has typed a query in the omnibox and committed it (either
552 // by pressing Enter or clicking on the preview). 569 // by pressing Enter or clicking on the preview).
553 // 2. We commit the preview to the tab strip, and tell the page. 570 // 2. We commit the preview to the tab strip, and tell the page.
554 // 3. The page will update the URL hash fragment with the query terms. 571 // 3. The page will update the URL hash fragment with the query terms.
555 // After steps 1 and 3, the omnibox will show the query terms. However, if 572 // After steps 1 and 3, the omnibox will show the query terms. However, if
556 // the URL we are committing at step 2 doesn't already have query terms, it 573 // the URL we are committing at step 2 doesn't already have query terms, it
557 // will flash for a brief moment as a plain URL. So, avoid that flicker by 574 // will flash for a brief moment as a plain URL. So, avoid that flicker by
(...skipping 12 matching lines...) Expand all
570 std::string query(UTF16ToUTF8(last_omnibox_text_)); 587 std::string query(UTF16ToUTF8(last_omnibox_text_));
571 if (type != INSTANT_COMMIT_PRESSED_ENTER) { 588 if (type != INSTANT_COMMIT_PRESSED_ENTER) {
572 query += UTF16ToUTF8(last_suggestion_.text); 589 query += UTF16ToUTF8(last_suggestion_.text);
573 // Update |last_omnibox_text_| so that the controller commits the proper 590 // Update |last_omnibox_text_| so that the controller commits the proper
574 // query if the user focuses the omnibox and presses Enter. 591 // query if the user focuses the omnibox and presses Enter.
575 last_omnibox_text_ += last_suggestion_.text; 592 last_omnibox_text_ += last_suggestion_.text;
576 } 593 }
577 entry->SetVirtualURL(GURL( 594 entry->SetVirtualURL(GURL(
578 url + "#q=" + 595 url + "#q=" +
579 net::EscapeQueryParamValue(query, true))); 596 net::EscapeQueryParamValue(query, true)));
580 chrome::search::SearchTabHelper::FromWebContents(preview)-> 597 chrome::search::SearchTabHelper::FromWebContents(preview.get())->
581 NavigationEntryUpdated(); 598 NavigationEntryUpdated();
582 } 599 }
583 } 600 }
584 601
585 // If the preview page has navigated since the last Update(), we need to add 602 // If the preview page has navigated since the last Update(), we need to add
586 // the navigation to history ourselves. Else, the page will navigate after 603 // the navigation to history ourselves. Else, the page will navigate after
587 // commit, and it will be added to history in the usual manner. 604 // commit, and it will be added to history in the usual manner.
588 const history::HistoryAddPageArgs& last_navigation = 605 const history::HistoryAddPageArgs& last_navigation =
589 loader_->last_navigation(); 606 overlay_->last_navigation();
590 if (!last_navigation.url.is_empty()) { 607 if (!last_navigation.url.is_empty()) {
591 content::NavigationEntry* entry = preview->GetController().GetActiveEntry(); 608 content::NavigationEntry* entry = preview->GetController().GetActiveEntry();
592 609
593 // The last navigation should be the same as the active entry if the loader 610 // The last navigation should be the same as the active entry if the overlay
594 // is in search mode. During navigation, the active entry could have 611 // is in search mode. During navigation, the active entry could have
595 // changed since DidCommitProvisionalLoadForFrame is called after the entry 612 // changed since DidCommitProvisionalLoadForFrame is called after the entry
596 // is changed. 613 // is changed.
597 // TODO(shishir): Should we commit the last navigation for 614 // TODO(shishir): Should we commit the last navigation for
598 // INSTANT_COMMIT_NAVIGATED. 615 // INSTANT_COMMIT_NAVIGATED.
599 DCHECK(type == INSTANT_COMMIT_NAVIGATED || 616 DCHECK(type == INSTANT_COMMIT_NAVIGATED ||
600 last_navigation.url == entry->GetURL()); 617 last_navigation.url == entry->GetURL());
601 618
602 // Add the page to history. 619 // Add the page to history.
603 HistoryTabHelper* history_tab_helper = 620 HistoryTabHelper* history_tab_helper =
604 HistoryTabHelper::FromWebContents(preview); 621 HistoryTabHelper::FromWebContents(preview.get());
605 history_tab_helper->UpdateHistoryForNavigation(last_navigation); 622 history_tab_helper->UpdateHistoryForNavigation(last_navigation);
606 623
607 // Update the page title. 624 // Update the page title.
608 history_tab_helper->UpdateHistoryPageTitle(*entry); 625 history_tab_helper->UpdateHistoryPageTitle(*entry);
609 } 626 }
610 627
611 // Add a fake history entry with a non-Instant search URL, so that search 628 // Add a fake history entry with a non-Instant search URL, so that search
612 // terms extraction (for autocomplete history matches) works. 629 // terms extraction (for autocomplete history matches) works.
613 HistoryService* history = HistoryServiceFactory::GetForProfile( 630 HistoryService* history = HistoryServiceFactory::GetForProfile(
614 Profile::FromBrowserContext(preview->GetBrowserContext()), 631 Profile::FromBrowserContext(preview->GetBrowserContext()),
615 Profile::EXPLICIT_ACCESS); 632 Profile::EXPLICIT_ACCESS);
616 if (history) { 633 if (history) {
617 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(), 634 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(),
618 history::RedirectList(), last_transition_type_, 635 history::RedirectList(), last_transition_type_,
619 history::SOURCE_BROWSED, false); 636 history::SOURCE_BROWSED, false);
620 } 637 }
621 638
622 preview->GetController().PruneAllButActive(); 639 preview->GetController().PruneAllButActive();
623 640
624 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { 641 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) {
625 content::WebContents* active_tab = browser_->GetActiveWebContents(); 642 content::WebContents* active_tab = browser_->GetActiveWebContents();
626 AddSessionStorageHistogram(extended_enabled_, active_tab, preview); 643 AddSessionStorageHistogram(extended_enabled_, active_tab, preview.get());
627 preview->GetController().CopyStateFromAndPrune( 644 preview->GetController().CopyStateFromAndPrune(
628 &active_tab->GetController()); 645 &active_tab->GetController());
629 } 646 }
630 647
631 // Browser takes ownership of the preview. 648 // Save notification source before we release the preview.
632 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); 649 const content::NotificationSource& notification_source =
650 content::Source<content::WebContents>(preview.get());
651
652 browser_->CommitInstant(preview.Pass(),
653 type == INSTANT_COMMIT_PRESSED_ALT_ENTER);
633 654
634 content::NotificationService::current()->Notify( 655 content::NotificationService::current()->Notify(
635 chrome::NOTIFICATION_INSTANT_COMMITTED, 656 chrome::NOTIFICATION_INSTANT_COMMITTED,
636 content::Source<content::WebContents>(preview), 657 notification_source,
637 content::NotificationService::NoDetails()); 658 content::NotificationService::NoDetails());
638 659
639 // Hide explicitly. See comments in HideLoader() for why. 660 // Hide explicitly. See comments in HideOverlay() for why.
640 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 661 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
641 662
642 // Delay deletion as we could've gotten here from an InstantLoader method. 663 // Delay deletion as we could've gotten here from an InstantOverlay method.
643 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); 664 MessageLoop::current()->DeleteSoon(FROM_HERE, overlay_.release());
644 665
645 // Try to create another loader immediately so that it is ready for the next 666 // Try to create another overlay immediately so that it is ready for the next
646 // user interaction. 667 // user interaction.
647 EnsureLoaderIsCurrent(false); 668 EnsureOverlayIsCurrent(false);
648 669
649 LOG_INSTANT_DEBUG_EVENT(this, "Committed"); 670 LOG_INSTANT_DEBUG_EVENT(this, "Committed");
650 return true; 671 return true;
651 } 672 }
652 673
653 void InstantController::OmniboxFocusChanged( 674 void InstantController::OmniboxFocusChanged(
654 OmniboxFocusState state, 675 OmniboxFocusState state,
655 OmniboxFocusChangeReason reason, 676 OmniboxFocusChangeReason reason,
656 gfx::NativeView view_gaining_focus) { 677 gfx::NativeView view_gaining_focus) {
657 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 678 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
658 "OmniboxFocusChanged: %d to %d for reason %d", omnibox_focus_state_, 679 "OmniboxFocusChanged: %d to %d for reason %d", omnibox_focus_state_,
659 state, reason)); 680 state, reason));
660 681
661 OmniboxFocusState old_focus_state = omnibox_focus_state_; 682 OmniboxFocusState old_focus_state = omnibox_focus_state_;
662 omnibox_focus_state_ = state; 683 omnibox_focus_state_ = state;
663 if (!extended_enabled_ && !instant_enabled_) 684 if (!extended_enabled_ && !instant_enabled_)
664 return; 685 return;
665 686
666 // Tell the page if the key capture mode changed unless the focus state 687 // Tell the page if the key capture mode changed unless the focus state
667 // changed because of TYPING. This is because in that case, the browser hasn't 688 // changed because of TYPING. This is because in that case, the browser hasn't
668 // really stopped capturing key strokes. 689 // really stopped capturing key strokes.
669 // 690 //
670 // (More practically, if we don't do this check, the page would receive 691 // (More practically, if we don't do this check, the page would receive
671 // onkeycapturechange before the corresponding onchange, and the page would 692 // onkeycapturechange before the corresponding onchange, and the page would
672 // have no way of telling whether the keycapturechange happened because of 693 // have no way of telling whether the keycapturechange happened because of
673 // some actual user action or just because they started typing.) 694 // some actual user action or just because they started typing.)
674 if (extended_enabled_ && GetPreviewContents() && 695 if (extended_enabled_ && GetPreviewContents() &&
675 reason != OMNIBOX_FOCUS_CHANGE_TYPING) 696 reason != OMNIBOX_FOCUS_CHANGE_TYPING) {
676 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); 697 const bool is_key_capture_enabled =
698 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE;
699 if (overlay_)
700 overlay_->KeyCaptureChanged(is_key_capture_enabled);
701 if (instant_tab_)
702 instant_tab_->KeyCaptureChanged(is_key_capture_enabled);
703 }
677 704
678 // If focus went from outside the omnibox to the omnibox, preload the default 705 // If focus went from outside the omnibox to the omnibox, preload the default
679 // search engine, in anticipation of the user typing a query. If the reverse 706 // search engine, in anticipation of the user typing a query. If the reverse
680 // happened, commit or discard the preview. 707 // happened, commit or discard the preview.
681 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) { 708 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) {
682 // On explicit user actions, ignore the Instant blacklist. 709 // On explicit user actions, ignore the Instant blacklist.
683 EnsureLoaderIsCurrent(reason == OMNIBOX_FOCUS_CHANGE_EXPLICIT); 710 EnsureOverlayIsCurrent(reason == OMNIBOX_FOCUS_CHANGE_EXPLICIT);
684 } else if (state == OMNIBOX_FOCUS_NONE && 711 } else if (state == OMNIBOX_FOCUS_NONE &&
685 old_focus_state != OMNIBOX_FOCUS_NONE) { 712 old_focus_state != OMNIBOX_FOCUS_NONE) {
686 OmniboxLostFocus(view_gaining_focus); 713 OmniboxLostFocus(view_gaining_focus);
687 } 714 }
688 } 715 }
689 716
690 void InstantController::SearchModeChanged( 717 void InstantController::SearchModeChanged(
691 const chrome::search::Mode& old_mode, 718 const chrome::search::Mode& old_mode,
692 const chrome::search::Mode& new_mode) { 719 const chrome::search::Mode& new_mode) {
693 if (!extended_enabled_) 720 if (!extended_enabled_)
694 return; 721 return;
695 722
696 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 723 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
697 "SearchModeChanged: [origin:mode] %d:%d to %d:%d", old_mode.origin, 724 "SearchModeChanged: [origin:mode] %d:%d to %d:%d", old_mode.origin,
698 old_mode.mode, new_mode.origin, new_mode.mode)); 725 old_mode.mode, new_mode.origin, new_mode.mode));
699 726
700 search_mode_ = new_mode; 727 search_mode_ = new_mode;
701 if (!new_mode.is_search_suggestions()) 728 if (!new_mode.is_search_suggestions())
702 HideLoader(); 729 HideOverlay();
703 730
704 if (loader_) 731 if (overlay_)
705 loader_->SearchModeChanged(new_mode); 732 overlay_->SearchModeChanged(new_mode);
706 733
707 ResetInstantTab(); 734 ResetInstantTab();
708 } 735 }
709 736
710 void InstantController::ActiveTabChanged() { 737 void InstantController::ActiveTabChanged() {
711 if (!extended_enabled_ && !instant_enabled_) 738 if (!extended_enabled_ && !instant_enabled_)
712 return; 739 return;
713 740
714 LOG_INSTANT_DEBUG_EVENT(this, "ActiveTabChanged"); 741 LOG_INSTANT_DEBUG_EVENT(this, "ActiveTabChanged");
715 742
716 // When switching tabs, always hide the preview, except if it's showing NTP 743 // When switching tabs, always hide the preview.
717 // content, and the new tab is also an NTP. 744 HideOverlay();
718 if (!search_mode_.is_ntp() || !model_.mode().is_ntp())
719 HideLoader();
720 745
721 if (extended_enabled_) 746 if (extended_enabled_)
722 ResetInstantTab(); 747 ResetInstantTab();
723 } 748 }
724 749
725 void InstantController::TabDeactivated(content::WebContents* contents) { 750 void InstantController::TabDeactivated(content::WebContents* contents) {
726 LOG_INSTANT_DEBUG_EVENT(this, "TabDeactivated"); 751 LOG_INSTANT_DEBUG_EVENT(this, "TabDeactivated");
727 if (extended_enabled_ && !contents->IsBeingDestroyed()) 752 if (extended_enabled_ && !contents->IsBeingDestroyed())
728 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); 753 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
729 } 754 }
730 755
731 void InstantController::SetInstantEnabled(bool instant_enabled, 756 void InstantController::SetInstantEnabled(bool instant_enabled,
732 bool use_local_preview_only) { 757 bool use_local_preview_only) {
733 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 758 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
734 "SetInstantEnabled: instant_enabled=%d, use_local_preview_only=%d", 759 "SetInstantEnabled: instant_enabled=%d, use_local_preview_only=%d",
735 instant_enabled, use_local_preview_only)); 760 instant_enabled, use_local_preview_only));
736 761
737 // Non extended mode does not care about |use_local_preview_only|. 762 // Non extended mode does not care about |use_local_preview_only|.
738 if (instant_enabled == instant_enabled_ && 763 if (instant_enabled == instant_enabled_ &&
739 (!extended_enabled_ || 764 (!extended_enabled_ ||
740 use_local_preview_only == use_local_preview_only_)) { 765 use_local_preview_only == use_local_preview_only_)) {
741 return; 766 return;
742 } 767 }
743 768
744 instant_enabled_ = instant_enabled; 769 instant_enabled_ = instant_enabled;
745 use_local_preview_only_ = use_local_preview_only; 770 use_local_preview_only_ = use_local_preview_only;
746 HideInternal(); 771 HideInternal();
747 loader_.reset(); 772 overlay_.reset();
748 if (extended_enabled_ || instant_enabled_) 773 if (extended_enabled_ || instant_enabled_)
749 EnsureLoaderIsCurrent(false); 774 EnsureOverlayIsCurrent(false);
775 if (extended_enabled_)
776 ResetNTP();
750 if (instant_tab_) 777 if (instant_tab_)
751 instant_tab_->SetDisplayInstantResults(instant_enabled_); 778 instant_tab_->SetDisplayInstantResults(instant_enabled_);
752 } 779 }
753 780
754 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { 781 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) {
755 if (!extended_enabled_) 782 if (!extended_enabled_)
756 return; 783 return;
757 784
758 if (loader_) 785 if (overlay_)
759 loader_->SendThemeBackgroundInfo(theme_info); 786 overlay_->SendThemeBackgroundInfo(theme_info);
787 if (ntp_)
788 ntp_->SendThemeBackgroundInfo(theme_info);
760 } 789 }
761 790
762 void InstantController::ThemeAreaHeightChanged(int height) { 791 void InstantController::ThemeAreaHeightChanged(int height) {
763 if (!extended_enabled_) 792 if (!extended_enabled_)
764 return; 793 return;
765 794
766 if (loader_) 795 if (overlay_)
767 loader_->SendThemeAreaHeight(height); 796 overlay_->SendThemeAreaHeight(height);
797 if (ntp_)
798 ntp_->SendThemeAreaHeight(height);
799 }
800
801 void InstantController::SwappedOverlayContents() {
802 model_.SetPreviewContents(GetPreviewContents());
803 }
804
805 void InstantController::FocusedOverlayContents() {
806 #if defined(USE_AURA)
807 // On aura the omnibox only receives a focus lost if we initiate the focus
808 // change. This does that.
809 if (!model_.mode().is_default())
810 browser_->InstantPreviewFocused();
811 #endif
812 }
813
814 void InstantController::ReloadOverlayIfStale() {
815 // The local popup is never stale.
816 if (overlay_ && overlay_->IsUsingLocalPreview())
817 return;
818
819 // If the preview is showing or the omnibox has focus, don't delete the
820 // overlay. It will get refreshed the next time the preview is hidden or the
821 // omnibox loses focus.
822 if ((!overlay_ || overlay_->is_stale()) &&
823 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE &&
824 model_.mode().is_default()) {
825 overlay_.reset();
826 EnsureOverlayIsCurrent(false);
827 }
828 }
829
830 void InstantController::LogDebugEvent(const std::string& info) const {
831 DVLOG(1) << info;
832
833 debug_events_.push_front(std::make_pair(
834 base::Time::Now().ToInternalValue(), info));
835 static const size_t kMaxDebugEventSize = 2000;
836 if (debug_events_.size() > kMaxDebugEventSize)
837 debug_events_.pop_back();
838 }
839
840 void InstantController::InstantPageRenderViewCreated(
841 const content::WebContents* contents) {
842 if (!extended_enabled_)
843 return;
844
845 // Ensure the searchbox API has the correct initial state.
846 if (IsContentsFrom(overlay(), contents)) {
847 overlay_->SetDisplayInstantResults(instant_enabled_);
848 overlay_->SearchModeChanged(search_mode_);
849 overlay_->KeyCaptureChanged(
850 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
851 overlay_->SetMarginSize(start_margin_, end_margin_);
852 overlay_->InitializeFonts();
853 } else if (IsContentsFrom(ntp(), contents)) {
854 ntp_->SetDisplayInstantResults(instant_enabled_);
855 ntp_->SetMarginSize(start_margin_, end_margin_);
856 ntp_->InitializeFonts();
857 }
858 }
859
860 void InstantController::InstantSupportDetermined(
861 const content::WebContents* contents,
862 bool supports_instant) {
863 if (IsContentsFrom(instant_tab(), contents)) {
864 if (!supports_instant)
865 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release());
866 } else if (IsContentsFrom(ntp(), contents)) {
867 if (supports_instant)
868 RemoveFromBlacklist(ntp_->instant_url());
869 else
870 BlacklistAndResetNTP();
871
872 content::NotificationService::current()->Notify(
873 chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
874 content::Source<InstantController>(this),
875 content::NotificationService::NoDetails());
876
877 } else if (IsContentsFrom(overlay(), contents)) {
878 if (supports_instant)
879 RemoveFromBlacklist(overlay_->instant_url());
880 else
881 BlacklistAndResetOverlay();
882
883 content::NotificationService::current()->Notify(
884 chrome::NOTIFICATION_INSTANT_OVERLAY_SUPPORT_DETERMINED,
885 content::Source<InstantController>(this),
886 content::NotificationService::NoDetails());
887 }
888 }
889
890 void InstantController::InstantPageRenderViewGone(
891 const content::WebContents* contents) {
892 if (IsContentsFrom(overlay(), contents))
893 BlacklistAndResetOverlay();
894 else if (IsContentsFrom(ntp(), contents))
895 BlacklistAndResetNTP();
896 }
897
898 void InstantController::InstantPageAboutToNavigateMainFrame(
899 const content::WebContents* contents,
900 const GURL& url) {
901 if (!IsContentsFrom(overlay(), contents))
902 return;
903
904 // If the page does not yet support instant, we allow redirects and other
905 // navigations to go through since the instant URL can redirect - e.g. to
906 // country specific pages.
907 if (!overlay_->supports_instant())
908 return;
909
910 GURL instant_url(overlay_->instant_url());
911
912 // If we are navigating to the instant URL, do nothing.
913 if (url == instant_url)
914 return;
915
916 // Commit the navigation if either:
917 // - The page is in NTP mode (so it could only navigate on a user click) or
918 // - The page is not in NTP mode and we are navigating to a URL with a
919 // different host or path than the instant URL. This enables the instant
920 // page when it is showing search results to change the query parameters
921 // and fragments of the URL without it navigating.
922 if (model_.mode().is_ntp() ||
923 (url.host() != instant_url.host() || url.path() != instant_url.path())) {
924 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
925 }
768 } 926 }
769 927
770 void InstantController::SetSuggestions( 928 void InstantController::SetSuggestions(
771 const content::WebContents* contents, 929 const content::WebContents* contents,
772 const std::vector<InstantSuggestion>& suggestions) { 930 const std::vector<InstantSuggestion>& suggestions) {
773 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); 931 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions");
774 932
775 // Ignore if the message is from an unexpected source. 933 // Ignore if the message is from an unexpected source.
776 if (instant_tab_) { 934 if (IsContentsFrom(ntp(), contents))
777 if (instant_tab_->contents() != contents)
778 return;
779 } else if (!loader_ || loader_->contents() != contents ||
780 !allow_preview_to_show_search_suggestions_) {
781 return; 935 return;
782 } 936 if (instant_tab_ && !IsContentsFrom(instant_tab(), contents))
937 return;
938 if (IsContentsFrom(overlay(), contents) &&
939 !allow_preview_to_show_search_suggestions_)
940 return;
783 941
784 InstantSuggestion suggestion; 942 InstantSuggestion suggestion;
785 if (!suggestions.empty()) 943 if (!suggestions.empty())
786 suggestion = suggestions[0]; 944 suggestion = suggestions[0];
787 945
788 if (instant_tab_ && search_mode_.is_search_results() && 946 if (instant_tab_ && search_mode_.is_search_results() &&
789 suggestion.behavior == INSTANT_COMPLETE_REPLACE) { 947 suggestion.behavior == INSTANT_COMPLETE_REPLACE) {
790 // Update |last_omnibox_text_| so that the controller commits the proper 948 // Update |last_omnibox_text_| so that the controller commits the proper
791 // query if the user focuses the omnibox and presses Enter. 949 // query if the user focuses the omnibox and presses Enter.
792 last_omnibox_text_ = suggestion.text; 950 last_omnibox_text_ = suggestion.text;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 last_suggestion_ = suggestion; 1011 last_suggestion_ = suggestion;
854 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1012 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
855 "SetInstantSuggestion: text='%s' behavior=%d", 1013 "SetInstantSuggestion: text='%s' behavior=%d",
856 UTF16ToUTF8(suggestion.text).c_str(), suggestion.behavior)); 1014 UTF16ToUTF8(suggestion.text).c_str(), suggestion.behavior));
857 browser_->SetInstantSuggestion(suggestion); 1015 browser_->SetInstantSuggestion(suggestion);
858 } else { 1016 } else {
859 last_suggestion_ = InstantSuggestion(); 1017 last_suggestion_ = InstantSuggestion();
860 } 1018 }
861 } 1019 }
862 1020
863 // Extended mode pages will call ShowLoader() when they are ready. 1021 // Extended mode pages will call ShowOverlay() when they are ready.
864 if (!extended_enabled_) 1022 if (!extended_enabled_)
865 ShowLoader(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); 1023 ShowOverlay(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT);
866 } 1024 }
867 1025
868 void InstantController::InstantSupportDetermined( 1026 void InstantController::ShowInstantPreview(const content::WebContents* contents,
869 const content::WebContents* contents, 1027 InstantShownReason reason,
870 bool supports_instant) { 1028 int height,
871 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1029 InstantSizeUnits units) {
872 "InstantSupportDetermined: supports_instant=%d", supports_instant)); 1030 if (extended_enabled_ && IsContentsFrom(overlay(), contents))
1031 ShowOverlay(reason, height, units);
1032 }
873 1033
874 if (instant_tab_ && instant_tab_->contents() == contents) { 1034 void InstantController::StartCapturingKeyStrokes(
875 if (!supports_instant) 1035 const content::WebContents* contents) {
876 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); 1036 if (!extended_enabled_)
877 return; 1037 return;
878 }
879 1038
880 if (loader_ && loader_->contents() == contents) { 1039 // Only honor the call if it comes from an active InstantTab or from an
881 if (supports_instant) { 1040 // InstantOverlay that is being shown.
882 if (blacklisted_urls_.erase(loader_->instant_url())) { 1041 if (IsContentsFrom(instant_tab(), contents) ||
883 RecordEventHistogram( 1042 (IsContentsFrom(overlay(), contents) && !model_.mode().is_default())) {
884 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST); 1043 browser_->FocusOmniboxInvisibly();
885 }
886 } else {
887 ++blacklisted_urls_[loader_->instant_url()];
888 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
889 HideInternal();
890 delete loader_->ReleaseContents();
891 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
892 EnsureLoaderIsCurrent(false);
893 }
894 content::NotificationService::current()->Notify(
895 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED,
896 content::Source<InstantController>(this),
897 content::NotificationService::NoDetails());
898 } 1044 }
899 } 1045 }
900 1046
901 void InstantController::ShowInstantPreview(InstantShownReason reason, 1047 void InstantController::StopCapturingKeyStrokes(
902 int height, 1048 content::WebContents* contents) {
903 InstantSizeUnits units) { 1049 // Nothing to do if omnibox doesn't have invisible focus.
904 if (extended_enabled_) 1050 if (!extended_enabled_ || omnibox_focus_state_ != OMNIBOX_FOCUS_INVISIBLE)
905 ShowLoader(reason, height, units);
906 }
907
908 void InstantController::StartCapturingKeyStrokes() {
909 // Ignore unless the loader is active and on the NTP.
910 if (extended_enabled_ && !instant_tab_ && model_.mode().is_ntp())
911 browser_->FocusOmniboxInvisibly();
912 }
913
914 void InstantController::StopCapturingKeyStrokes() {
915 // Ignore unless the loader is active and on the NTP, and the omnibox has
916 // invisible focus.
917 if (extended_enabled_ && !instant_tab_ && model_.mode().is_ntp() &&
918 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE)
919 loader_->contents()->Focus();
920 }
921
922 void InstantController::SwappedWebContents() {
923 model_.SetPreviewContents(GetPreviewContents());
924 }
925
926 void InstantController::InstantLoaderContentsFocused() {
927 #if defined(USE_AURA)
928 // On aura the omnibox only receives a focus lost if we initiate the focus
929 // change. This does that.
930 if (!model_.mode().is_default())
931 browser_->InstantPreviewFocused();
932 #endif
933 }
934
935 void InstantController::InstantLoaderRenderViewGone() {
936 ++blacklisted_urls_[loader_->instant_url()];
937 HideInternal();
938 delete loader_->ReleaseContents();
939 // Delay deletion as we have gotten here from an InstantLoader method.
940 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release());
941 EnsureLoaderIsCurrent(false);
942 }
943
944 void InstantController::InstantLoaderAboutToNavigateMainFrame(const GURL& url) {
945 // If the page does not yet support instant, we allow redirects and other
946 // navigations to go through since the instant URL can redirect - e.g. to
947 // country specific pages.
948 if (!loader_->supports_instant())
949 return; 1051 return;
950 1052
951 GURL instant_url(loader_->instant_url()); 1053 // Only honor the call if it comes from an active InstantTab or from an
952 1054 // InstantOverlay that is being shown.
953 // If we are navigating to the instant URL, do nothing. 1055 if (IsContentsFrom(instant_tab(), contents) ||
954 if (url == instant_url) 1056 (IsContentsFrom(overlay(), contents) && !model_.mode().is_default())) {
955 return; 1057 contents->Focus();
956
957 // Commit the navigation if either:
958 // - The page is in NTP mode (so it could only navigate on a user click) or
959 // - The page is not in NTP mode and we are navigating to a URL with a
960 // different host or path than the instant URL. This enables the instant
961 // page when it is showing search results to change the query parameters
962 // and fragments of the URL without it navigating.
963 if (model_.mode().is_ntp() ||
964 (url.host() != instant_url.host() || url.path() != instant_url.path())) {
965 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
966 } 1058 }
967 } 1059 }
968 1060
969 void InstantController::InstantLoaderRenderViewCreated() { 1061 void InstantController::NavigateToURL(const content::WebContents* contents,
1062 const GURL& url,
1063 content::PageTransition transition) {
1064 // TODO(samarth): handle case where contents are no longer "active" (e.g. user
1065 // has switched tabs).
970 if (!extended_enabled_) 1066 if (!extended_enabled_)
971 return; 1067 return;
972 1068 if (overlay_)
973 // Ensure the searchbox API has the correct initial state. 1069 HideOverlay();
974 loader_->SetDisplayInstantResults(instant_enabled_); 1070 browser_->OpenURLInCurrentTab(url, transition);
975 loader_->SearchModeChanged(search_mode_);
976 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
977 loader_->SetMarginSize(start_margin_, end_margin_);
978 loader_->InitializeFonts();
979 } 1071 }
980 1072
981 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { 1073 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) {
982 // If the preview is showing custom NTP content, don't hide it, commit it 1074 // If the preview is showing custom NTP content, don't hide it, commit it
983 // (no matter where the user clicked) or try to recreate it. 1075 // (no matter where the user clicked) or try to recreate it.
984 if (model_.mode().is_ntp()) 1076 if (model_.mode().is_ntp())
985 return; 1077 return;
986 1078
987 // If the preview is not showing at all, recreate it if it's stale. 1079 // If the preview is not showing at all, recreate it if it's stale.
988 if (model_.mode().is_default()) { 1080 if (model_.mode().is_default()) {
989 OnStaleLoader(); 1081 ReloadOverlayIfStale();
990 MaybeSwitchToRemoteLoader(); 1082 MaybeSwitchToRemoteOverlay();
991 return; 1083 return;
992 } 1084 }
993 1085
994 // The preview is showing search suggestions. If GetPreviewContents() is NULL, 1086 // The preview is showing search suggestions. If GetPreviewContents() is NULL,
995 // we are in the commit path. Don't do anything. 1087 // we are in the commit path. Don't do anything.
996 if (!GetPreviewContents()) 1088 if (!GetPreviewContents())
997 return; 1089 return;
998 1090
999 #if defined(OS_MACOSX) 1091 #if defined(OS_MACOSX)
1000 // TODO(sreeram): See if Mac really needs this special treatment. 1092 // TODO(sreeram): See if Mac really needs this special treatment.
1001 if (!loader_->is_pointer_down_from_activate()) 1093 if (!overlay_->is_pointer_down_from_activate())
1002 HideLoader(); 1094 HideOverlay();
1003 #else 1095 #else
1004 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), 1096 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus),
1005 loader_->contents())) 1097 overlay_->contents()))
1006 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); 1098 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
1007 else 1099 else
1008 HideLoader(); 1100 HideOverlay();
1009 #endif 1101 #endif
1010 } 1102 }
1011 1103
1012 void InstantController::NavigateToURL(const GURL& url, 1104 void InstantController::ResetNTP() {
1013 content::PageTransition transition) { 1105 ntp_.reset();
1014 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1106 std::string instant_url;
1015 "NavigateToURL: url='%s'", url.spec().c_str())); 1107 if (!GetInstantURL(browser_->profile(), false, &instant_url))
1108 return;
1016 1109
1017 if (!extended_enabled_) 1110 ntp_.reset(new InstantNTP(this, instant_url));
1018 return; 1111 ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents(),
1019 if (loader_) 1112 base::Bind(&InstantController::ResetNTP,
1020 HideLoader(); 1113 base::Unretained(this)));
1021 browser_->OpenURLInCurrentTab(url, transition);
1022 } 1114 }
1023 1115
1024 void InstantController::LogDebugEvent(const std::string& info) const { 1116 bool InstantController::EnsureOverlayIsCurrent(bool ignore_blacklist) {
1025 DVLOG(1) << info;
1026
1027 debug_events_.push_front(std::make_pair(
1028 base::Time::Now().ToInternalValue(), info));
1029 static const size_t kMaxDebugEventSize = 2000;
1030 if (debug_events_.size() > kMaxDebugEventSize)
1031 debug_events_.pop_back();
1032 }
1033
1034 bool InstantController::EnsureLoaderIsCurrent(bool ignore_blacklist) {
1035 // If there's no active tab, the browser is closing. 1117 // If there's no active tab, the browser is closing.
1036 const content::WebContents* active_tab = browser_->GetActiveWebContents(); 1118 const content::WebContents* active_tab = browser_->GetActiveWebContents();
1037 if (!active_tab) 1119 if (!active_tab)
1038 return false; 1120 return false;
1039 1121
1122 Profile* profile = Profile::FromBrowserContext(
1123 active_tab->GetBrowserContext());
1040 std::string instant_url; 1124 std::string instant_url;
1041 if (!GetInstantURL(active_tab, ignore_blacklist, &instant_url)) { 1125 if (!GetInstantURL(profile, ignore_blacklist, &instant_url)) {
1042 // If we are in extended mode, fallback to the local popup. 1126 // If we are in extended mode, fallback to the local popup.
1043 if (extended_enabled_) 1127 if (extended_enabled_)
1044 instant_url = kLocalOmniboxPopupURL; 1128 instant_url = kLocalOmniboxPopupURL;
1045 else 1129 else
1046 return false; 1130 return false;
1047 } 1131 }
1048 1132
1049 if (!loader_ || loader_->instant_url() != instant_url) 1133 if (!overlay_ || overlay_->instant_url() != instant_url)
1050 CreateLoader(instant_url, active_tab); 1134 CreateOverlay(instant_url, active_tab);
1051 1135
1052 return true; 1136 return true;
1053 } 1137 }
1054 1138
1055 void InstantController::CreateLoader(const std::string& instant_url, 1139 void InstantController::CreateOverlay(const std::string& instant_url,
1056 const content::WebContents* active_tab) { 1140 const content::WebContents* active_tab) {
1057 // Update theme info so that the loader picks up the correct fonts. 1141 // Update theme info so that the loader picks up the correct fonts.
1058 if (extended_enabled_) 1142 if (extended_enabled_)
1059 browser_->UpdateThemeInfoForPreview(); 1143 browser_->UpdateThemeInfoForPreview();
1060 1144
1061 HideInternal(); 1145 HideInternal();
1062 loader_.reset(new InstantLoader(this, instant_url)); 1146 overlay_.reset(new InstantOverlay(this, instant_url));
1063 loader_->InitContents(active_tab); 1147 overlay_->InitContents(browser_->profile(), active_tab);
1064 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1148 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
1065 "CreateLoader: instant_url='%s'", instant_url.c_str())); 1149 "CreateOverlay: instant_url='%s'", instant_url.c_str()));
1066
1067 // Restart the stale loader timer.
1068 stale_loader_timer_.Start(FROM_HERE,
1069 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this,
1070 &InstantController::OnStaleLoader);
1071 } 1150 }
1072 1151
1073 void InstantController::OnStaleLoader() { 1152 void InstantController::MaybeSwitchToRemoteOverlay() {
1074 // The local popup is never stale. 1153 if (!overlay_ || omnibox_focus_state_ != OMNIBOX_FOCUS_NONE ||
1075 if (loader_ && loader_->IsUsingLocalPreview())
1076 return;
1077
1078 // If the preview is showing or the omnibox has focus, don't delete the
1079 // loader. It will get refreshed the next time the preview is hidden or the
1080 // omnibox loses focus.
1081 if (!stale_loader_timer_.IsRunning() &&
1082 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE &&
1083 model_.mode().is_default()) {
1084 loader_.reset();
1085 EnsureLoaderIsCurrent(false);
1086 }
1087 }
1088
1089 void InstantController::MaybeSwitchToRemoteLoader() {
1090 if (!loader_ || omnibox_focus_state_ != OMNIBOX_FOCUS_NONE ||
1091 !model_.mode().is_default()) { 1154 !model_.mode().is_default()) {
1092 return; 1155 return;
1093 } 1156 }
1094 1157
1095 EnsureLoaderIsCurrent(false); 1158 EnsureOverlayIsCurrent(false);
1096 } 1159 }
1097 1160
1098 void InstantController::ResetInstantTab() { 1161 void InstantController::ResetInstantTab() {
1099 // Do not wire up the InstantTab if instant should only use local previews, to 1162 // Do not wire up the InstantTab if instant should only use local previews, to
1100 // prevent it from sending data to the page. 1163 // prevent it from sending data to the page.
1101 if (search_mode_.is_origin_search() && !use_local_preview_only_) { 1164 if (!search_mode_.is_origin_default() && !use_local_preview_only_) {
1102 content::WebContents* active_tab = browser_->GetActiveWebContents(); 1165 content::WebContents* active_tab = browser_->GetActiveWebContents();
1103 if (!instant_tab_ || active_tab != instant_tab_->contents()) { 1166 if (!instant_tab_ || active_tab != instant_tab_->contents()) {
1104 instant_tab_.reset(new InstantTab(this, active_tab)); 1167 instant_tab_.reset(new InstantTab(this));
1105 instant_tab_->Init(); 1168 instant_tab_->Init(active_tab);
1106 instant_tab_->SetDisplayInstantResults(instant_enabled_); 1169 instant_tab_->SetDisplayInstantResults(instant_enabled_);
1107 instant_tab_->SetMarginSize(start_margin_, end_margin_); 1170 instant_tab_->SetMarginSize(start_margin_, end_margin_);
1108 instant_tab_->InitializeFonts(); 1171 instant_tab_->InitializeFonts();
1172 instant_tab_->KeyCaptureChanged(
1173 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1109 } 1174 }
1110 1175
1111 // Hide the |loader_| since we are now using |instant_tab_| instead. 1176 // Hide the |overlay_| since we are now using |instant_tab_| instead.
1112 HideLoader(); 1177 HideOverlay();
1113 } else { 1178 } else {
1114 instant_tab_.reset(); 1179 instant_tab_.reset();
1115 } 1180 }
1116 } 1181 }
1117 1182
1118 void InstantController::HideLoader() { 1183 void InstantController::HideOverlay() {
1119 HideInternal(); 1184 HideInternal();
1120 OnStaleLoader(); 1185 ReloadOverlayIfStale();
1121 MaybeSwitchToRemoteLoader(); 1186 MaybeSwitchToRemoteOverlay();
1122 } 1187 }
1123 1188
1124 void InstantController::HideInternal() { 1189 void InstantController::HideInternal() {
1125 LOG_INSTANT_DEBUG_EVENT(this, "Hide"); 1190 LOG_INSTANT_DEBUG_EVENT(this, "Hide");
1126 1191
1127 // If GetPreviewContents() returns NULL, either we're already in the desired 1192 // If GetPreviewContents() returns NULL, either we're already in the desired
1128 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't 1193 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't
1129 // change the state just yet; else we may hide the preview unnecessarily. 1194 // change the state just yet; else we may hide the preview unnecessarily.
1130 // Instead, the state will be set correctly after the commit is done. 1195 // Instead, the state will be set correctly after the commit is done.
1131 if (GetPreviewContents()) { 1196 if (GetPreviewContents()) {
1132 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 1197 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
1133 allow_preview_to_show_search_suggestions_ = false; 1198 allow_preview_to_show_search_suggestions_ = false;
1134 1199
1135 // Send a message asking the preview to clear out old results. 1200 // Send a message asking the preview to clear out old results.
1136 loader_->Update(string16(), 0, 0, true); 1201 overlay_->Update(string16(), 0, 0, true);
1137 } 1202 }
1138 1203
1139 // Clear the first interaction timestamp for later use. 1204 // Clear the first interaction timestamp for later use.
1140 first_interaction_time_ = base::Time(); 1205 first_interaction_time_ = base::Time();
1141 } 1206 }
1142 1207
1143 void InstantController::ShowLoader(InstantShownReason reason, 1208 void InstantController::ShowOverlay(InstantShownReason reason,
1144 int height, 1209 int height,
1145 InstantSizeUnits units) { 1210 InstantSizeUnits units) {
1146 // If we are on a committed search results page, the |loader_| is not in use. 1211 // If we are on a committed search results page, the |overlay_| is not in use.
1147 if (instant_tab_) 1212 if (instant_tab_)
1148 return; 1213 return;
1149 1214
1150 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1215 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
1151 "Show: reason=%d height=%d units=%d", reason, height, units)); 1216 "Show: reason=%d height=%d units=%d", reason, height, units));
1152 1217
1153 // Must be on NTP to show NTP content. 1218 // INSTANT_SHOWN_CUSTOM_NTP_CONTENT is no longer supported.
1154 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) 1219 // TODO(samarth): remove once the server has been updated.
1220 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT)
1155 return; 1221 return;
1156 1222
1157 // Must have updated omnibox after the last HideLoader() to show suggestions. 1223 // Must have updated omnibox after the last HideOverlay() to show suggestions.
1158 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS || 1224 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS ||
1159 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) && 1225 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) &&
1160 !allow_preview_to_show_search_suggestions_) 1226 !allow_preview_to_show_search_suggestions_)
1161 return; 1227 return;
1162 1228
1163 // The page is trying to hide itself. Hide explicitly (i.e., don't use 1229 // The page is trying to hide itself. Hide explicitly (i.e., don't use
1164 // HideLoader()) so that it can change its mind. 1230 // HideOverlay()) so that it can change its mind.
1165 if (height == 0) { 1231 if (height == 0) {
1166 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 1232 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
1167 return; 1233 return;
1168 } 1234 }
1169 1235
1170 // If the preview is being shown for the first time since the user started 1236 // If the preview is being shown for the first time since the user started
1171 // typing, record a histogram value. 1237 // typing, record a histogram value.
1172 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { 1238 if (!first_interaction_time_.is_null() && model_.mode().is_default()) {
1173 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; 1239 base::TimeDelta delta = base::Time::Now() - first_interaction_time_;
1174 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); 1240 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta);
1175 } 1241 }
1176 1242
1177 // Show at 100% height except in the following cases: 1243 // Show at 100% height except in the following cases:
1178 // - The local omnibox popup is being loaded. 1244 // - The local omnibox popup is being loaded.
1179 // - Instant is disabled. The page needs to be able to show only a dropdown. 1245 // - Instant is disabled. The page needs to be able to show only a dropdown.
1180 // - The page wants to show custom NTP content. 1246 // - The page wants to show custom NTP content.
1181 // - The page is over a website other than search or an NTP, and is not 1247 // - The page is over a website other than search or an NTP, and is not
1182 // already showing at 100% height. 1248 // already showing at 100% height.
1183 if (loader_->IsUsingLocalPreview() || !instant_enabled_ || 1249 if (overlay_->IsUsingLocalPreview() || !instant_enabled_ ||
1184 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || 1250 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT ||
1185 (search_mode_.is_origin_default() && !IsFullHeight(model_))) 1251 (search_mode_.is_origin_default() && !IsFullHeight(model_)))
1186 model_.SetPreviewState(search_mode_, height, units); 1252 model_.SetPreviewState(search_mode_, height, units);
1187 else 1253 else
1188 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); 1254 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT);
1189 1255
1190 // If the user clicked on a query suggestion, also go ahead and commit the 1256 // If the user clicked on a query suggestion, also go ahead and commit the
1191 // overlay. This is necessary because if the overlay was partially visible 1257 // overlay. This is necessary because if the overlay was partially visible
1192 // when the suggestion was clicked, the click itself would not commit the 1258 // when the suggestion was clicked, the click itself would not commit the
1193 // overlay (because we're not full height). 1259 // overlay (because we're not full height).
1194 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) 1260 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION)
1195 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); 1261 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION);
1196 } 1262 }
1197 1263
1198 void InstantController::SendPopupBoundsToPage() { 1264 void InstantController::SendPopupBoundsToPage() {
1199 if (last_popup_bounds_ == popup_bounds_ || !loader_ || 1265 if (last_popup_bounds_ == popup_bounds_ || !overlay_ ||
1200 loader_->is_pointer_down_from_activate()) 1266 overlay_->is_pointer_down_from_activate())
1201 return; 1267 return;
1202 1268
1203 last_popup_bounds_ = popup_bounds_; 1269 last_popup_bounds_ = popup_bounds_;
1204 gfx::Rect preview_bounds = browser_->GetInstantBounds(); 1270 gfx::Rect preview_bounds = browser_->GetInstantBounds();
1205 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); 1271 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds);
1206 1272
1207 // Translate into window coordinates. 1273 // Translate into window coordinates.
1208 if (!intersection.IsEmpty()) { 1274 if (!intersection.IsEmpty()) {
1209 intersection.Offset(-preview_bounds.origin().x(), 1275 intersection.Offset(-preview_bounds.origin().x(),
1210 -preview_bounds.origin().y()); 1276 -preview_bounds.origin().y());
1211 } 1277 }
1212 1278
1213 // In the current Chrome UI, these must always be true so they sanity check 1279 // In the current Chrome UI, these must always be true so they sanity check
1214 // the above operations. In a future UI, these may be removed or adjusted. 1280 // the above operations. In a future UI, these may be removed or adjusted.
1215 // There is no point in sanity-checking |intersection.y()| because the omnibox 1281 // There is no point in sanity-checking |intersection.y()| because the omnibox
1216 // can be placed anywhere vertically relative to the preview (for example, in 1282 // can be placed anywhere vertically relative to the preview (for example, in
1217 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). 1283 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds).
1218 DCHECK_LE(0, intersection.x()); 1284 DCHECK_LE(0, intersection.x());
1219 DCHECK_LE(0, intersection.width()); 1285 DCHECK_LE(0, intersection.width());
1220 DCHECK_LE(0, intersection.height()); 1286 DCHECK_LE(0, intersection.height());
1221 1287
1222 loader_->SetPopupBounds(intersection); 1288 overlay_->SetPopupBounds(intersection);
1223 } 1289 }
1224 1290
1225 bool InstantController::GetInstantURL(const content::WebContents* active_tab, 1291 bool InstantController::GetInstantURL(Profile* profile,
1226 bool ignore_blacklist, 1292 bool ignore_blacklist,
1227 std::string* instant_url) const { 1293 std::string* instant_url) const {
1228 DCHECK(active_tab); 1294 DCHECK(profile);
1229 instant_url->clear(); 1295 instant_url->clear();
1230 1296
1231 if (extended_enabled_ && use_local_preview_only_) { 1297 if (extended_enabled_ && use_local_preview_only_) {
1232 *instant_url = kLocalOmniboxPopupURL; 1298 *instant_url = kLocalOmniboxPopupURL;
1233 return true; 1299 return true;
1234 } 1300 }
1235 1301
1236 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( 1302 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
1237 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> 1303 profile)->GetDefaultSearchProvider();
1238 GetDefaultSearchProvider();
1239 1304
1240 if (!template_url) { 1305 if (!template_url) {
1241 LOG_INSTANT_DEBUG_EVENT(this, "GetInstantURL: No template URL"); 1306 LOG_INSTANT_DEBUG_EVENT(this, "GetInstantURL: No template URL");
1242 return false; 1307 return false;
1243 } 1308 }
1244 1309
1245 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1310 CommandLine* command_line = CommandLine::ForCurrentProcess();
1246 if (command_line->HasSwitch(switches::kInstantURL)) 1311 if (command_line->HasSwitch(switches::kInstantURL))
1247 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); 1312 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL);
1248 1313
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); 1374 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST);
1310 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1375 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
1311 "GetInstantURL: Instant URL blacklisted: url=%s", 1376 "GetInstantURL: Instant URL blacklisted: url=%s",
1312 instant_url->c_str())); 1377 instant_url->c_str()));
1313 return false; 1378 return false;
1314 } 1379 }
1315 } 1380 }
1316 1381
1317 return true; 1382 return true;
1318 } 1383 }
1384
1385 void InstantController::BlacklistAndResetNTP() {
1386 ++blacklisted_urls_[ntp_->instant_url()];
1387 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
1388 ignore_result(ntp_->ReleaseContents());
1389 MessageLoop::current()->DeleteSoon(FROM_HERE, ntp_.release());
1390 ResetNTP();
1391 }
1392
1393 void InstantController::BlacklistAndResetOverlay() {
1394 ++blacklisted_urls_[overlay_->instant_url()];
1395 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
1396 HideInternal();
1397 ignore_result(overlay_->ReleaseContents());
1398 MessageLoop::current()->DeleteSoon(FROM_HERE, overlay_.release());
1399 EnsureOverlayIsCurrent(false);
1400 }
1401
1402 void InstantController::RemoveFromBlacklist(const std::string& url) {
1403 if (blacklisted_urls_.erase(url)) {
1404 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST);
1405 }
1406 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698