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

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

Powered by Google App Engine
This is Rietveld 408576698