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

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"
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 ContentsFrom(const InstantPage* page,
dhollowa 2013/01/29 02:37:53 nit: IsContentsFrom
samarth 2013/01/29 05:42:01 Done.
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 if (!extended_enabled_ || !ntp_)
dhollowa 2013/01/29 02:37:53 Seems like the caller is in error if they try to r
samarth 2013/01/29 05:42:01 Done. Note that as I mentioned earlier, ntp_ may
406 return scoped_ptr<content::WebContents>(NULL);
407
408 LOG_INSTANT_DEBUG_EVENT(this, "ReleaseNTPContents");
409
410 scoped_ptr<content::WebContents> ntp_contents = ntp_->ReleaseContents();
411 ntp_.reset();
412 ResetNTP();
413 return ntp_contents.Pass();
414 }
415
402 // TODO(tonyg): This method only fires when the omnibox bounds change. It also 416 // 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). 417 // needs to fire when the preview bounds change (e.g.: open/close info bar).
404 void InstantController::SetPopupBounds(const gfx::Rect& bounds) { 418 void InstantController::SetPopupBounds(const gfx::Rect& bounds) {
405 if (!extended_enabled_ && !instant_enabled_) 419 if (!extended_enabled_ && !instant_enabled_)
406 return; 420 return;
407 421
408 if (popup_bounds_ == bounds) 422 if (popup_bounds_ == bounds)
409 return; 423 return;
410 424
411 popup_bounds_ = bounds; 425 popup_bounds_ = bounds;
412 if (popup_bounds_.height() > last_popup_bounds_.height()) { 426 if (popup_bounds_.height() > last_popup_bounds_.height()) {
413 update_bounds_timer_.Stop(); 427 update_bounds_timer_.Stop();
414 SendPopupBoundsToPage(); 428 SendPopupBoundsToPage();
415 } else if (!update_bounds_timer_.IsRunning()) { 429 } else if (!update_bounds_timer_.IsRunning()) {
416 update_bounds_timer_.Start(FROM_HERE, 430 update_bounds_timer_.Start(FROM_HERE,
417 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this, 431 base::TimeDelta::FromMilliseconds(kUpdateBoundsDelayMS), this,
418 &InstantController::SendPopupBoundsToPage); 432 &InstantController::SendPopupBoundsToPage);
419 } 433 }
420 } 434 }
421 435
422 void InstantController::SetMarginSize(int start, int end) { 436 void InstantController::SetMarginSize(int start, int end) {
423 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end)) 437 if (!extended_enabled_ || (start_margin_ == start && end_margin_ == end))
424 return; 438 return;
425 439
426 start_margin_ = start; 440 start_margin_ = start;
427 end_margin_ = end; 441 end_margin_ = end;
428 if (loader_) 442 if (overlay_)
429 loader_->SetMarginSize(start_margin_, end_margin_); 443 overlay_->SetMarginSize(start_margin_, end_margin_);
444 if (ntp_)
445 ntp_->SetMarginSize(start_margin_, end_margin_);
430 if (instant_tab_) 446 if (instant_tab_)
431 instant_tab_->SetMarginSize(start_margin_, end_margin_); 447 instant_tab_->SetMarginSize(start_margin_, end_margin_);
432 } 448 }
433 449
434 void InstantController::HandleAutocompleteResults( 450 void InstantController::HandleAutocompleteResults(
435 const std::vector<AutocompleteProvider*>& providers) { 451 const std::vector<AutocompleteProvider*>& providers) {
436 if (!extended_enabled_) 452 if (!extended_enabled_)
437 return; 453 return;
438 454
439 if (!instant_tab_ && !loader_) 455 if (!instant_tab_ && !overlay_)
440 return; 456 return;
441 457
442 DVLOG(1) << "AutocompleteResults:"; 458 DVLOG(1) << "AutocompleteResults:";
443 std::vector<InstantAutocompleteResult> results; 459 std::vector<InstantAutocompleteResult> results;
444 for (ACProviders::const_iterator provider = providers.begin(); 460 for (ACProviders::const_iterator provider = providers.begin();
445 provider != providers.end(); ++provider) { 461 provider != providers.end(); ++provider) {
446 for (ACMatches::const_iterator match = (*provider)->matches().begin(); 462 for (ACMatches::const_iterator match = (*provider)->matches().begin();
447 match != (*provider)->matches().end(); ++match) { 463 match != (*provider)->matches().end(); ++match) {
448 InstantAutocompleteResult result; 464 InstantAutocompleteResult result;
449 result.provider = UTF8ToUTF16((*provider)->GetName()); 465 result.provider = UTF8ToUTF16((*provider)->GetName());
450 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); 466 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type));
451 result.description = match->description; 467 result.description = match->description;
452 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); 468 result.destination_url = UTF8ToUTF16(match->destination_url.spec());
453 result.transition = match->transition; 469 result.transition = match->transition;
454 result.relevance = match->relevance; 470 result.relevance = match->relevance;
455 DVLOG(1) << " " << result.relevance << " " << result.type << " " 471 DVLOG(1) << " " << result.relevance << " " << result.type << " "
456 << result.provider << " " << result.destination_url << " '" 472 << result.provider << " " << result.destination_url << " '"
457 << result.description << "' " << result.transition; 473 << result.description << "' " << result.transition;
458 results.push_back(result); 474 results.push_back(result);
459 } 475 }
460 } 476 }
461 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 477 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
462 "HandleAutocompleteResults: total_results=%d", 478 "HandleAutocompleteResults: total_results=%d",
463 static_cast<int>(results.size()))); 479 static_cast<int>(results.size())));
464 480
465 if (instant_tab_) 481 if (instant_tab_)
466 instant_tab_->SendAutocompleteResults(results); 482 instant_tab_->SendAutocompleteResults(results);
467 else 483 else
468 loader_->SendAutocompleteResults(results); 484 overlay_->SendAutocompleteResults(results);
469 } 485 }
470 486
471 bool InstantController::OnUpOrDownKeyPressed(int count) { 487 bool InstantController::OnUpOrDownKeyPressed(int count) {
472 if (!extended_enabled_) 488 if (!extended_enabled_)
473 return false; 489 return false;
474 490
475 if (!instant_tab_ && !loader_) 491 if (!instant_tab_ && !overlay_)
476 return false; 492 return false;
477 493
478 if (instant_tab_) 494 if (instant_tab_)
479 instant_tab_->UpOrDownKeyPressed(count); 495 instant_tab_->UpOrDownKeyPressed(count);
480 else 496 else
481 loader_->UpOrDownKeyPressed(count); 497 overlay_->UpOrDownKeyPressed(count);
482 498
483 return true; 499 return true;
484 } 500 }
485 501
486 content::WebContents* InstantController::GetPreviewContents() const { 502 content::WebContents* InstantController::GetPreviewContents() const {
487 return loader_ ? loader_->contents() : NULL; 503 return overlay_ ? overlay_->contents() : NULL;
488 } 504 }
489 505
490 bool InstantController::IsPreviewingSearchResults() const { 506 bool InstantController::IsPreviewingSearchResults() const {
491 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && 507 return model_.mode().is_search_suggestions() && IsFullHeight(model_) &&
492 (last_match_was_search_ || 508 (last_match_was_search_ ||
493 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); 509 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER);
494 } 510 }
495 511
496 bool InstantController::CommitIfPossible(InstantCommitType type) { 512 bool InstantController::CommitIfPossible(InstantCommitType type) {
497 if (!extended_enabled_ && !instant_enabled_) 513 if (!extended_enabled_ && !instant_enabled_)
(...skipping 16 matching lines...) Expand all
514 return true; 530 return true;
515 } 531 }
516 return false; 532 return false;
517 } 533 }
518 534
519 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) 535 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED)
520 return false; 536 return false;
521 537
522 // There may re-entrance here, from the call to browser_->CommitInstant below, 538 // There may re-entrance here, from the call to browser_->CommitInstant below,
523 // which can cause a TabDeactivated notification which gets back here. 539 // which can cause a TabDeactivated notification which gets back here.
524 // In this case, loader_->ReleaseContents() was called already. 540 // In this case, overlay_->ReleaseContents() was called already.
525 if (!GetPreviewContents()) 541 if (!GetPreviewContents())
526 return false; 542 return false;
527 543
528 // Never commit the local omnibox. 544 // Never commit the local omnibox.
529 if (loader_->IsUsingLocalPreview()) 545 if (overlay_->IsUsingLocalPreview())
530 return false; 546 return false;
531 547
532 if (type == INSTANT_COMMIT_FOCUS_LOST) 548 if (type == INSTANT_COMMIT_FOCUS_LOST)
533 loader_->Cancel(last_omnibox_text_); 549 overlay_->Cancel(last_omnibox_text_);
534 else if (type != INSTANT_COMMIT_NAVIGATED && 550 else if (type != INSTANT_COMMIT_NAVIGATED &&
535 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) 551 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION)
536 loader_->Submit(last_omnibox_text_); 552 overlay_->Submit(last_omnibox_text_);
537 553
538 content::WebContents* preview = loader_->ReleaseContents(); 554 scoped_ptr<content::WebContents> preview = overlay_->ReleaseContents();
539 555
540 if (extended_enabled_) { 556 if (extended_enabled_) {
541 // Consider what's happening: 557 // Consider what's happening:
542 // 1. The user has typed a query in the omnibox and committed it (either 558 // 1. The user has typed a query in the omnibox and committed it (either
543 // by pressing Enter or clicking on the preview). 559 // by pressing Enter or clicking on the preview).
544 // 2. We commit the preview to the tab strip, and tell the page. 560 // 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. 561 // 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 562 // 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 563 // 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 564 // 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. 565 // 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 566 // 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. 567 // to NavigationEntry to keep track of what the correct query, if any, is.
552 content::NavigationEntry* entry = 568 content::NavigationEntry* entry =
553 preview->GetController().GetVisibleEntry(); 569 preview->GetController().GetVisibleEntry();
554 std::string url = entry->GetVirtualURL().spec(); 570 std::string url = entry->GetVirtualURL().spec();
555 if (!google_util::IsInstantExtendedAPIGoogleSearchUrl(url) && 571 if (!google_util::IsInstantExtendedAPIGoogleSearchUrl(url) &&
556 google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN, 572 google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN,
557 google_util::ALLOW_NON_STANDARD_PORTS)) { 573 google_util::ALLOW_NON_STANDARD_PORTS)) {
558 // Hitting ENTER searches for what the user typed, so use 574 // Hitting ENTER searches for what the user typed, so use
559 // last_omnibox_text_. Clicking on the overlay commits what is currently 575 // last_omnibox_text_. Clicking on the overlay commits what is currently
560 // showing, so add in the gray text in that case. 576 // showing, so add in the gray text in that case.
561 std::string query(UTF16ToUTF8(last_omnibox_text_)); 577 std::string query(UTF16ToUTF8(last_omnibox_text_));
562 if (type != INSTANT_COMMIT_PRESSED_ENTER) 578 if (type != INSTANT_COMMIT_PRESSED_ENTER)
563 query += UTF16ToUTF8(last_suggestion_.text); 579 query += UTF16ToUTF8(last_suggestion_.text);
564 entry->SetVirtualURL(GURL( 580 entry->SetVirtualURL(GURL(
565 url + "#q=" + 581 url + "#q=" +
566 net::EscapeQueryParamValue(query, true))); 582 net::EscapeQueryParamValue(query, true)));
567 chrome::search::SearchTabHelper::FromWebContents(preview)-> 583 chrome::search::SearchTabHelper::FromWebContents(preview.get())->
568 NavigationEntryUpdated(); 584 NavigationEntryUpdated();
569 } 585 }
570 } 586 }
571 587
572 // If the preview page has navigated since the last Update(), we need to add 588 // 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 589 // the navigation to history ourselves. Else, the page will navigate after
574 // commit, and it will be added to history in the usual manner. 590 // commit, and it will be added to history in the usual manner.
575 const history::HistoryAddPageArgs& last_navigation = 591 const history::HistoryAddPageArgs& last_navigation =
576 loader_->last_navigation(); 592 overlay_->last_navigation();
577 if (!last_navigation.url.is_empty()) { 593 if (!last_navigation.url.is_empty()) {
578 content::NavigationEntry* entry = preview->GetController().GetActiveEntry(); 594 content::NavigationEntry* entry = preview->GetController().GetActiveEntry();
579 595
580 // The last navigation should be the same as the active entry if the loader 596 // 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 597 // is in search mode. During navigation, the active entry could have
582 // changed since DidCommitProvisionalLoadForFrame is called after the entry 598 // changed since DidCommitProvisionalLoadForFrame is called after the entry
583 // is changed. 599 // is changed.
584 // TODO(shishir): Should we commit the last navigation for 600 // TODO(shishir): Should we commit the last navigation for
585 // INSTANT_COMMIT_NAVIGATED. 601 // INSTANT_COMMIT_NAVIGATED.
586 DCHECK(type == INSTANT_COMMIT_NAVIGATED || 602 DCHECK(type == INSTANT_COMMIT_NAVIGATED ||
587 last_navigation.url == entry->GetURL()); 603 last_navigation.url == entry->GetURL());
588 604
589 // Add the page to history. 605 // Add the page to history.
590 HistoryTabHelper* history_tab_helper = 606 HistoryTabHelper* history_tab_helper =
591 HistoryTabHelper::FromWebContents(preview); 607 HistoryTabHelper::FromWebContents(preview.get());
592 history_tab_helper->UpdateHistoryForNavigation(last_navigation); 608 history_tab_helper->UpdateHistoryForNavigation(last_navigation);
593 609
594 // Update the page title. 610 // Update the page title.
595 history_tab_helper->UpdateHistoryPageTitle(*entry); 611 history_tab_helper->UpdateHistoryPageTitle(*entry);
596 } 612 }
597 613
598 // Add a fake history entry with a non-Instant search URL, so that search 614 // Add a fake history entry with a non-Instant search URL, so that search
599 // terms extraction (for autocomplete history matches) works. 615 // terms extraction (for autocomplete history matches) works.
600 HistoryService* history = HistoryServiceFactory::GetForProfile( 616 HistoryService* history = HistoryServiceFactory::GetForProfile(
601 Profile::FromBrowserContext(preview->GetBrowserContext()), 617 Profile::FromBrowserContext(preview->GetBrowserContext()),
602 Profile::EXPLICIT_ACCESS); 618 Profile::EXPLICIT_ACCESS);
603 if (history) { 619 if (history) {
604 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(), 620 history->AddPage(url_for_history_, base::Time::Now(), NULL, 0, GURL(),
605 history::RedirectList(), last_transition_type_, 621 history::RedirectList(), last_transition_type_,
606 history::SOURCE_BROWSED, false); 622 history::SOURCE_BROWSED, false);
607 } 623 }
608 624
609 preview->GetController().PruneAllButActive(); 625 preview->GetController().PruneAllButActive();
610 626
611 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) { 627 if (type != INSTANT_COMMIT_PRESSED_ALT_ENTER) {
612 content::WebContents* active_tab = browser_->GetActiveWebContents(); 628 content::WebContents* active_tab = browser_->GetActiveWebContents();
613 AddSessionStorageHistogram(extended_enabled_, active_tab, preview); 629 AddSessionStorageHistogram(extended_enabled_, active_tab, preview.get());
614 preview->GetController().CopyStateFromAndPrune( 630 preview->GetController().CopyStateFromAndPrune(
615 &active_tab->GetController()); 631 &active_tab->GetController());
616 } 632 }
617 633
618 // Browser takes ownership of the preview. 634 // Save notification source before we release the preview.
619 browser_->CommitInstant(preview, type == INSTANT_COMMIT_PRESSED_ALT_ENTER); 635 const content::NotificationSource& notification_source =
636 content::Source<content::WebContents>(preview.get());
637
638 browser_->CommitInstant(preview.Pass(),
639 type == INSTANT_COMMIT_PRESSED_ALT_ENTER);
620 640
621 content::NotificationService::current()->Notify( 641 content::NotificationService::current()->Notify(
622 chrome::NOTIFICATION_INSTANT_COMMITTED, 642 chrome::NOTIFICATION_INSTANT_COMMITTED,
623 content::Source<content::WebContents>(preview), 643 notification_source,
624 content::NotificationService::NoDetails()); 644 content::NotificationService::NoDetails());
625 645
626 // Hide explicitly. See comments in HideLoader() for why. 646 // Hide explicitly. See comments in HideOverlay() for why.
627 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 647 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
628 648
629 // Delay deletion as we could've gotten here from an InstantLoader method. 649 // Delay deletion as we could've gotten here from an InstantOverlay method.
630 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); 650 MessageLoop::current()->DeleteSoon(FROM_HERE, overlay_.release());
631 651
632 // Try to create another loader immediately so that it is ready for the next 652 // Try to create another overlay immediately so that it is ready for the next
633 // user interaction. 653 // user interaction.
634 EnsureLoaderIsCurrent(); 654 EnsureOverlayIsCurrent();
635 655
636 LOG_INSTANT_DEBUG_EVENT(this, "Committed"); 656 LOG_INSTANT_DEBUG_EVENT(this, "Committed");
637 return true; 657 return true;
638 } 658 }
639 659
640 void InstantController::OmniboxFocusChanged( 660 void InstantController::OmniboxFocusChanged(
641 OmniboxFocusState state, 661 OmniboxFocusState state,
642 OmniboxFocusChangeReason reason, 662 OmniboxFocusChangeReason reason,
643 gfx::NativeView view_gaining_focus) { 663 gfx::NativeView view_gaining_focus) {
644 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 664 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
645 "OmniboxFocusChanged: %d to %d for reason %d", omnibox_focus_state_, 665 "OmniboxFocusChanged: %d to %d for reason %d", omnibox_focus_state_,
646 state, reason)); 666 state, reason));
647 667
648 OmniboxFocusState old_focus_state = omnibox_focus_state_; 668 OmniboxFocusState old_focus_state = omnibox_focus_state_;
649 omnibox_focus_state_ = state; 669 omnibox_focus_state_ = state;
650 if (!extended_enabled_ && !instant_enabled_) 670 if (!extended_enabled_ && !instant_enabled_)
651 return; 671 return;
652 672
653 // Tell the page if the key capture mode changed unless the focus state 673 // 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 674 // changed because of TYPING. This is because in that case, the browser hasn't
655 // really stopped capturing key strokes. 675 // really stopped capturing key strokes.
656 // 676 //
657 // (More practically, if we don't do this check, the page would receive 677 // (More practically, if we don't do this check, the page would receive
658 // onkeycapturechange before the corresponding onchange, and the page would 678 // onkeycapturechange before the corresponding onchange, and the page would
659 // have no way of telling whether the keycapturechange happened because of 679 // have no way of telling whether the keycapturechange happened because of
660 // some actual user action or just because they started typing.) 680 // some actual user action or just because they started typing.)
661 if (extended_enabled_ && GetPreviewContents() && 681 if (extended_enabled_ && GetPreviewContents() &&
662 reason != OMNIBOX_FOCUS_CHANGE_TYPING) 682 reason != OMNIBOX_FOCUS_CHANGE_TYPING) {
663 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); 683 const bool is_key_capture_enabled =
684 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE;
685 if (overlay_)
686 overlay_->KeyCaptureChanged(is_key_capture_enabled);
687 if (instant_tab_)
688 instant_tab_->KeyCaptureChanged(is_key_capture_enabled);
689 }
664 690
665 // If focus went from outside the omnibox to the omnibox, preload the default 691 // 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 692 // search engine, in anticipation of the user typing a query. If the reverse
667 // happened, commit or discard the preview. 693 // happened, commit or discard the preview.
668 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) 694 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE)
669 EnsureLoaderIsCurrent(); 695 EnsureOverlayIsCurrent();
670 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE) 696 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE)
671 OmniboxLostFocus(view_gaining_focus); 697 OmniboxLostFocus(view_gaining_focus);
672 } 698 }
673 699
674 void InstantController::SearchModeChanged( 700 void InstantController::SearchModeChanged(
675 const chrome::search::Mode& old_mode, 701 const chrome::search::Mode& old_mode,
676 const chrome::search::Mode& new_mode) { 702 const chrome::search::Mode& new_mode) {
677 if (!extended_enabled_) 703 if (!extended_enabled_)
678 return; 704 return;
679 705
680 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 706 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
681 "SearchModeChanged: [origin:mode] %d:%d to %d:%d", old_mode.origin, 707 "SearchModeChanged: [origin:mode] %d:%d to %d:%d", old_mode.origin,
682 old_mode.mode, new_mode.origin, new_mode.mode)); 708 old_mode.mode, new_mode.origin, new_mode.mode));
683 709
684 search_mode_ = new_mode; 710 search_mode_ = new_mode;
685 if (!new_mode.is_search_suggestions()) 711 if (!new_mode.is_search_suggestions())
686 HideLoader(); 712 HideOverlay();
687 713
688 if (loader_) 714 if (overlay_)
689 loader_->SearchModeChanged(new_mode); 715 overlay_->SearchModeChanged(new_mode);
690 716
691 ResetInstantTab(); 717 ResetInstantTab();
692 } 718 }
693 719
694 void InstantController::ActiveTabChanged() { 720 void InstantController::ActiveTabChanged() {
695 if (!extended_enabled_ && !instant_enabled_) 721 if (!extended_enabled_ && !instant_enabled_)
696 return; 722 return;
697 723
698 LOG_INSTANT_DEBUG_EVENT(this, "ActiveTabChanged"); 724 LOG_INSTANT_DEBUG_EVENT(this, "ActiveTabChanged");
699 725
700 // When switching tabs, always hide the preview, except if it's showing NTP 726 // When switching tabs, always hide the preview.
701 // content, and the new tab is also an NTP. 727 HideOverlay();
702 if (!search_mode_.is_ntp() || !model_.mode().is_ntp())
703 HideLoader();
704 728
705 if (extended_enabled_) 729 if (extended_enabled_)
706 ResetInstantTab(); 730 ResetInstantTab();
707 } 731 }
708 732
709 void InstantController::TabDeactivated(content::WebContents* contents) { 733 void InstantController::TabDeactivated(content::WebContents* contents) {
710 LOG_INSTANT_DEBUG_EVENT(this, "TabDeactivated"); 734 LOG_INSTANT_DEBUG_EVENT(this, "TabDeactivated");
711 if (extended_enabled_ && !contents->IsBeingDestroyed()) 735 if (extended_enabled_ && !contents->IsBeingDestroyed())
712 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); 736 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
713 } 737 }
714 738
715 void InstantController::SetInstantEnabled(bool instant_enabled) { 739 void InstantController::SetInstantEnabled(bool instant_enabled) {
716 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 740 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
717 "SetInstantEnabled: %d", instant_enabled)); 741 "SetInstantEnabled: %d", instant_enabled));
718 instant_enabled_ = instant_enabled; 742 instant_enabled_ = instant_enabled;
719 HideInternal(); 743 HideInternal();
720 loader_.reset(); 744 overlay_.reset();
721 if (extended_enabled_ || instant_enabled_) 745 if (extended_enabled_ || instant_enabled_)
722 EnsureLoaderIsCurrent(); 746 EnsureOverlayIsCurrent();
747 if (extended_enabled_)
748 ResetNTP();
723 if (instant_tab_) 749 if (instant_tab_)
724 instant_tab_->SetDisplayInstantResults(instant_enabled_); 750 instant_tab_->SetDisplayInstantResults(instant_enabled_);
725 } 751 }
726 752
727 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) { 753 void InstantController::ThemeChanged(const ThemeBackgroundInfo& theme_info) {
728 if (!extended_enabled_) 754 if (!extended_enabled_)
729 return; 755 return;
730 756
731 if (loader_) 757 if (overlay_)
732 loader_->SendThemeBackgroundInfo(theme_info); 758 overlay_->SendThemeBackgroundInfo(theme_info);
759 if (ntp_)
760 ntp_->SendThemeBackgroundInfo(theme_info);
733 } 761 }
734 762
735 void InstantController::ThemeAreaHeightChanged(int height) { 763 void InstantController::ThemeAreaHeightChanged(int height) {
736 if (!extended_enabled_) 764 if (!extended_enabled_)
737 return; 765 return;
738 766
739 if (loader_) 767 if (overlay_)
740 loader_->SendThemeAreaHeight(height); 768 overlay_->SendThemeAreaHeight(height);
769 if (ntp_)
770 ntp_->SendThemeAreaHeight(height);
771 }
772
773 void InstantController::SwappedOverlayContents() {
774 model_.SetPreviewContents(GetPreviewContents());
775 }
776
777 void InstantController::FocusedOverlayContents() {
778 #if defined(USE_AURA)
779 // On aura the omnibox only receives a focus lost if we initiate the focus
780 // change. This does that.
781 if (!model_.mode().is_default())
782 browser_->InstantPreviewFocused();
783 #endif
784 }
785
786 void InstantController::HandleStaleOverlay() {
787 // The local popup is never stale.
788 if (overlay_ && overlay_->IsUsingLocalPreview())
789 return;
790
791 // If the preview is showing or the omnibox has focus, don't delete the
792 // overlay. It will get refreshed the next time the preview is hidden or the
793 // omnibox loses focus.
794 if ((!overlay_ || overlay_->is_stale()) &&
795 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE &&
796 model_.mode().is_default()) {
797 overlay_.reset();
798 EnsureOverlayIsCurrent();
799 }
800 }
801
802 void InstantController::LogDebugEvent(const std::string& info) const {
803 DVLOG(1) << info;
804
805 debug_events_.push_front(std::make_pair(
806 base::Time::Now().ToInternalValue(), info));
807 static const size_t kMaxDebugEventSize = 2000;
808 if (debug_events_.size() > kMaxDebugEventSize)
809 debug_events_.pop_back();
810 }
811
812 void InstantController::InstantSupportDetermined(
813 const content::WebContents* contents,
814 bool supports_instant) {
815 if (ContentsFrom(instant_tab_.get(), contents)) {
816 if (!supports_instant)
817 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release());
818 } else if (ContentsFrom(ntp_.get(), contents)) {
819 if (supports_instant)
820 RemoveFromBlacklist(ntp_->instant_url());
821 else
822 BlacklistAndResetNTP();
823 } else if (ContentsFrom(overlay_.get(), contents)) {
824 if (supports_instant)
825 RemoveFromBlacklist(overlay_->instant_url());
826 else
827 BlacklistAndResetOverlay();
828
829 content::NotificationService::current()->Notify(
dhollowa 2013/01/29 02:37:53 This doesn't indicate *which* page's Instant suppo
samarth 2013/01/29 05:42:01 Luckily it turns out the only user of this is the
830 chrome::NOTIFICATION_INSTANT_SUPPORT_DETERMINED,
831 content::Source<InstantController>(this),
832 content::NotificationService::NoDetails());
833 }
834 }
835
836 void InstantController::InstantPageRenderViewGone(
837 const content::WebContents* contents) {
838 if (ContentsFrom(overlay_.get(), contents))
839 BlacklistAndResetOverlay();
840 else if (ContentsFrom(ntp_.get(), contents))
841 BlacklistAndResetNTP();
842 }
843
844 void InstantController::InstantPageAboutToNavigateMainFrame(
845 const content::WebContents* contents,
846 const GURL& url) {
847 if (!ContentsFrom(overlay_.get(), contents))
848 return;
849
850 // If the page does not yet support instant, we allow redirects and other
851 // navigations to go through since the instant URL can redirect - e.g. to
852 // country specific pages.
853 if (!overlay_->supports_instant())
854 return;
855
856 GURL instant_url(overlay_->instant_url());
857
858 // If we are navigating to the instant URL, do nothing.
859 if (url == instant_url)
860 return;
861
862 // Commit the navigation if either:
863 // - The page is in NTP mode (so it could only navigate on a user click) or
864 // - The page is not in NTP mode and we are navigating to a URL with a
865 // different host or path than the instant URL. This enables the instant
866 // page when it is showing search results to change the query parameters
867 // and fragments of the URL without it navigating.
868 if (model_.mode().is_ntp() ||
869 (url.host() != instant_url.host() || url.path() != instant_url.path())) {
870 CommitIfPossible(INSTANT_COMMIT_NAVIGATED);
871 }
741 } 872 }
742 873
743 void InstantController::SetSuggestions( 874 void InstantController::SetSuggestions(
744 const content::WebContents* contents, 875 const content::WebContents* contents,
745 const std::vector<InstantSuggestion>& suggestions) { 876 const std::vector<InstantSuggestion>& suggestions) {
746 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); 877 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions");
747 878
748 // Ignore if the message is from an unexpected source. 879 // Ignore if the message is from an unexpected source.
749 if (instant_tab_) { 880 if (ContentsFrom(ntp_.get(), 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; 881 return;
755 } 882 if (instant_tab_ && !ContentsFrom(instant_tab_.get(), contents))
883 return;
884 if (ContentsFrom(overlay_.get(), contents) &&
885 !allow_preview_to_show_search_suggestions_)
886 return;
756 887
757 InstantSuggestion suggestion; 888 InstantSuggestion suggestion;
758 if (!suggestions.empty()) 889 if (!suggestions.empty())
759 suggestion = suggestions[0]; 890 suggestion = suggestions[0];
760 891
761 if (instant_tab_ && search_mode_.is_search_results() && 892 if (instant_tab_ && search_mode_.is_search_results() &&
762 suggestion.behavior == INSTANT_COMPLETE_REPLACE) { 893 suggestion.behavior == INSTANT_COMPLETE_REPLACE) {
763 // This means a committed page in state search called setValue(). We should 894 // This means a committed page in state search called setValue(). We should
764 // update the omnibox to reflect what the search page says. 895 // update the omnibox to reflect what the search page says.
765 browser_->SetInstantSuggestion(suggestion); 896 browser_->SetInstantSuggestion(suggestion);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 last_suggestion_ = suggestion; 954 last_suggestion_ = suggestion;
824 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 955 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
825 "SetInstantSuggestion: text='%s' behavior=%d", 956 "SetInstantSuggestion: text='%s' behavior=%d",
826 UTF16ToUTF8(suggestion.text).c_str(), suggestion.behavior)); 957 UTF16ToUTF8(suggestion.text).c_str(), suggestion.behavior));
827 browser_->SetInstantSuggestion(suggestion); 958 browser_->SetInstantSuggestion(suggestion);
828 } else { 959 } else {
829 last_suggestion_ = InstantSuggestion(); 960 last_suggestion_ = InstantSuggestion();
830 } 961 }
831 } 962 }
832 963
833 // Extended mode pages will call ShowLoader() when they are ready. 964 // Extended mode pages will call ShowOverlay() when they are ready.
834 if (!extended_enabled_) 965 if (!extended_enabled_)
835 ShowLoader(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT); 966 ShowOverlay(INSTANT_SHOWN_QUERY_SUGGESTIONS, 100, INSTANT_SIZE_PERCENT);
836 } 967 }
837 968
838 void InstantController::InstantSupportDetermined( 969 void InstantController::ShowInstantPreview(const content::WebContents* contents,
839 const content::WebContents* contents, 970 InstantShownReason reason,
840 bool supports_instant) { 971 int height,
841 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 972 InstantSizeUnits units) {
842 "InstantSupportDetermined: supports_instant= %d", supports_instant)); 973 if (extended_enabled_ && ContentsFrom(overlay_.get(), contents))
974 ShowOverlay(reason, height, units);
975 }
843 976
844 if (instant_tab_ && instant_tab_->contents() == contents) { 977 void InstantController::StartCapturingKeyStrokes(
845 if (!supports_instant) 978 const content::WebContents* contents) {
846 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); 979 if (!extended_enabled_)
847 return; 980 return;
848 }
849 981
850 if (loader_ && loader_->contents() == contents) { 982 // Only honor the call if it comes from an active InstantTab or from an
851 if (supports_instant) { 983 // InstantOverlay that is being shown.
852 if (blacklisted_urls_.erase(loader_->instant_url())) { 984 if (ContentsFrom(instant_tab_.get(), contents) ||
853 RecordEventHistogram( 985 (ContentsFrom(overlay_.get(), contents) && !model_.mode().is_default())) {
854 INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST); 986 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 } 987 }
869 } 988 }
870 989
871 void InstantController::ShowInstantPreview(InstantShownReason reason, 990 void InstantController::StopCapturingKeyStrokes(
872 int height, 991 content::WebContents* contents) {
873 InstantSizeUnits units) { 992 // Nothing to do if omnibox doesn't have invisible focus.
874 if (extended_enabled_) 993 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; 994 return;
920 995
921 GURL instant_url(loader_->instant_url()); 996 // Only honor the call if it comes from an active InstantTab or from an
922 997 // InstantOverlay that is being shown.
923 // If we are navigating to the instant URL, do nothing. 998 if (ContentsFrom(instant_tab_.get(), contents) ||
924 if (url == instant_url) 999 (ContentsFrom(overlay_.get(), contents) && !model_.mode().is_default())) {
925 return; 1000 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 } 1001 }
937 } 1002 }
938 1003
1004 void InstantController::NavigateToURL(const content::WebContents* contents,
1005 const GURL& url,
1006 content::PageTransition transition) {
1007 // TODO(samarth): handle case where contents are no longer "active" (e.g. user
1008 // has switched tabs).
1009 if (!extended_enabled_)
1010 return;
1011 if (overlay_)
1012 HideOverlay();
1013 browser_->OpenURLInCurrentTab(url, transition);
1014 }
1015
939 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { 1016 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) {
940 // If the preview is showing custom NTP content, don't hide it, commit it 1017 // 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. 1018 // (no matter where the user clicked) or try to recreate it.
942 if (model_.mode().is_ntp()) 1019 if (model_.mode().is_ntp())
943 return; 1020 return;
944 1021
945 // If the preview is not showing at all, recreate it if it's stale. 1022 // If the preview is not showing at all, recreate it if it's stale.
946 if (model_.mode().is_default()) { 1023 if (model_.mode().is_default()) {
947 OnStaleLoader(); 1024 HandleStaleOverlay();
948 return; 1025 return;
949 } 1026 }
950 1027
951 // The preview is showing search suggestions. If GetPreviewContents() is NULL, 1028 // The preview is showing search suggestions. If GetPreviewContents() is NULL,
952 // we are in the commit path. Don't do anything. 1029 // we are in the commit path. Don't do anything.
953 if (!GetPreviewContents()) 1030 if (!GetPreviewContents())
954 return; 1031 return;
955 1032
956 #if defined(OS_MACOSX) 1033 #if defined(OS_MACOSX)
957 // TODO(sreeram): See if Mac really needs this special treatment. 1034 // TODO(sreeram): See if Mac really needs this special treatment.
958 if (!loader_->is_pointer_down_from_activate()) 1035 if (!overlay_->is_pointer_down_from_activate())
959 HideLoader(); 1036 HideOverlay();
960 #else 1037 #else
961 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), 1038 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus),
962 loader_->contents())) 1039 overlay_->contents()))
963 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); 1040 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST);
964 else 1041 else
965 HideLoader(); 1042 HideOverlay();
966 #endif 1043 #endif
967 } 1044 }
968 1045
969 void InstantController::NavigateToURL(const GURL& url, 1046 void InstantController::ResetNTP() {
970 content::PageTransition transition) { 1047 std::string instant_url;
971 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1048 if (!GetInstantURL(browser_->profile(), &instant_url))
972 "NavigateToURL: url='%s'", url.spec().c_str())); 1049 return;
973 1050
974 if (!extended_enabled_) 1051 ntp_.reset(new InstantNTP(this, instant_url));
975 return; 1052 ntp_->InitContents(browser_->profile(), browser_->GetActiveWebContents(),
976 if (loader_) 1053 base::Bind(&InstantController::ResetNTP,
977 HideLoader(); 1054 base::Unretained(this)));
978 browser_->OpenURLInCurrentTab(url, transition); 1055
1056 // Ensure the searchbox API has the correct initial state.
1057 if (extended_enabled_) {
1058 browser_->UpdateThemeInfoForPreview();
1059 ntp_->SetDisplayInstantResults(instant_enabled_);
1060 ntp_->SetMarginSize(start_margin_, end_margin_);
1061 }
979 } 1062 }
980 1063
981 void InstantController::LogDebugEvent(const std::string& info) const { 1064 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. 1065 // If there's no active tab, the browser is closing.
993 const content::WebContents* active_tab = browser_->GetActiveWebContents(); 1066 const content::WebContents* active_tab = browser_->GetActiveWebContents();
994 if (!active_tab) 1067 if (!active_tab)
995 return false; 1068 return false;
996 1069
1070 Profile* profile = Profile::FromBrowserContext(
1071 active_tab->GetBrowserContext());
997 std::string instant_url; 1072 std::string instant_url;
998 if (!GetInstantURL(active_tab, &instant_url)) { 1073 if (!GetInstantURL(profile, &instant_url)) {
999 // If we are in extended mode, fallback to the local popup. 1074 // If we are in extended mode, fallback to the local popup.
1000 if (extended_enabled_) 1075 if (extended_enabled_)
1001 instant_url = kLocalOmniboxPopupURL; 1076 instant_url = kLocalOmniboxPopupURL;
1002 else 1077 else
1003 return false; 1078 return false;
1004 } 1079 }
1005 1080
1006 if (!loader_ || loader_->instant_url() != instant_url) 1081 if (!overlay_ || overlay_->instant_url() != instant_url)
1007 CreateLoader(instant_url, active_tab); 1082 CreateOverlay(instant_url, active_tab);
1008 1083
1009 return true; 1084 return true;
1010 } 1085 }
1011 1086
1012 void InstantController::CreateLoader(const std::string& instant_url, 1087 void InstantController::CreateOverlay(const std::string& instant_url,
1013 const content::WebContents* active_tab) { 1088 const content::WebContents* active_tab) {
1014 HideInternal(); 1089 HideInternal();
1015 loader_.reset(new InstantLoader(this, instant_url)); 1090 overlay_.reset(new InstantOverlay(this, instant_url));
1016 loader_->InitContents(active_tab); 1091 overlay_->InitContents(browser_->profile(), active_tab);
1017 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1092 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
1018 "CreateLoader: instant_url='%s'", instant_url.c_str())); 1093 "CreateOverlay: instant_url='%s'", instant_url.c_str()));
1019 1094
1020 // Ensure the searchbox API has the correct initial state. 1095 // Ensure the searchbox API has the correct initial state.
1021 if (extended_enabled_) { 1096 if (extended_enabled_) {
1022 browser_->UpdateThemeInfoForPreview(); 1097 browser_->UpdateThemeInfoForPreview();
1023 loader_->SetDisplayInstantResults(instant_enabled_); 1098 overlay_->SetDisplayInstantResults(instant_enabled_);
1024 loader_->SearchModeChanged(search_mode_); 1099 overlay_->SearchModeChanged(search_mode_);
1025 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); 1100 overlay_->KeyCaptureChanged(
1026 loader_->SetMarginSize(start_margin_, end_margin_); 1101 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1027 } 1102 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 } 1103 }
1049 } 1104 }
1050 1105
1051 void InstantController::ResetInstantTab() { 1106 void InstantController::ResetInstantTab() {
1052 // Do not wire up the InstantTab if instant should only use local previews, to 1107 // Do not wire up the InstantTab if instant should only use local previews, to
1053 // prevent it from sending data to the page. 1108 // prevent it from sending data to the page.
1054 if (search_mode_.is_origin_search() && !use_local_preview_only_) { 1109 if (!search_mode_.is_origin_default() && !use_local_preview_only_) {
1055 content::WebContents* active_tab = browser_->GetActiveWebContents(); 1110 content::WebContents* active_tab = browser_->GetActiveWebContents();
1056 if (!instant_tab_ || active_tab != instant_tab_->contents()) { 1111 if (!instant_tab_ || active_tab != instant_tab_->contents()) {
1057 instant_tab_.reset(new InstantTab(this, active_tab)); 1112 instant_tab_.reset(new InstantTab(this));
1058 instant_tab_->Init(); 1113 instant_tab_->Init(active_tab);
1059 instant_tab_->SetDisplayInstantResults(instant_enabled_); 1114 instant_tab_->SetDisplayInstantResults(instant_enabled_);
1060 instant_tab_->SetMarginSize(start_margin_, end_margin_); 1115 instant_tab_->SetMarginSize(start_margin_, end_margin_);
1116 instant_tab_->KeyCaptureChanged(
1117 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE);
1061 } 1118 }
1062 1119
1063 // Hide the |loader_| since we are now using |instant_tab_| instead. 1120 // Hide the |overlay_| since we are now using |instant_tab_| instead.
1064 HideLoader(); 1121 HideOverlay();
1065 } else { 1122 } else {
1066 instant_tab_.reset(); 1123 instant_tab_.reset();
1067 } 1124 }
1068 } 1125 }
1069 1126
1070 void InstantController::HideLoader() { 1127 void InstantController::HideOverlay() {
1071 HideInternal(); 1128 HideInternal();
1072 OnStaleLoader(); 1129 HandleStaleOverlay();
1073 } 1130 }
1074 1131
1075 void InstantController::HideInternal() { 1132 void InstantController::HideInternal() {
1076 LOG_INSTANT_DEBUG_EVENT(this, "Hide"); 1133 LOG_INSTANT_DEBUG_EVENT(this, "Hide");
1077 1134
1078 // If GetPreviewContents() returns NULL, either we're already in the desired 1135 // 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 1136 // 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. 1137 // 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. 1138 // Instead, the state will be set correctly after the commit is done.
1082 if (GetPreviewContents()) { 1139 if (GetPreviewContents()) {
1083 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 1140 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
1084 allow_preview_to_show_search_suggestions_ = false; 1141 allow_preview_to_show_search_suggestions_ = false;
1085 1142
1086 // Send a message asking the preview to clear out old results. 1143 // Send a message asking the preview to clear out old results.
1087 loader_->Update(string16(), 0, 0, true); 1144 overlay_->Update(string16(), 0, 0, true);
1088 } 1145 }
1089 1146
1090 // Clear the first interaction timestamp for later use. 1147 // Clear the first interaction timestamp for later use.
1091 first_interaction_time_ = base::Time(); 1148 first_interaction_time_ = base::Time();
1092 } 1149 }
1093 1150
1094 void InstantController::ShowLoader(InstantShownReason reason, 1151 void InstantController::ShowOverlay(InstantShownReason reason,
1095 int height, 1152 int height,
1096 InstantSizeUnits units) { 1153 InstantSizeUnits units) {
1097 // If we are on a committed search results page, the |loader_| is not in use. 1154 // If we are on a committed search results page, the |overlay_| is not in use.
1098 if (instant_tab_) 1155 if (instant_tab_)
1099 return; 1156 return;
1100 1157
1101 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1158 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
1102 "Show: reason=%d height=%d units=%d", reason, height, units)); 1159 "Show: reason=%d height=%d units=%d", reason, height, units));
1103 1160
1104 // Must be on NTP to show NTP content. 1161 // INSTANT_SHOWN_CUSTOM_NTP_CONTENT is no longer supported.
1105 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT && !search_mode_.is_ntp()) 1162 // TODO(samarth): remove once the server has been updated.
1163 if (reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT)
1106 return; 1164 return;
1107 1165
1108 // Must have updated omnibox after the last HideLoader() to show suggestions. 1166 // Must have updated omnibox after the last HideOverlay() to show suggestions.
1109 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS || 1167 if ((reason == INSTANT_SHOWN_QUERY_SUGGESTIONS ||
1110 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) && 1168 reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) &&
1111 !allow_preview_to_show_search_suggestions_) 1169 !allow_preview_to_show_search_suggestions_)
1112 return; 1170 return;
1113 1171
1114 // The page is trying to hide itself. Hide explicitly (i.e., don't use 1172 // The page is trying to hide itself. Hide explicitly (i.e., don't use
1115 // HideLoader()) so that it can change its mind. 1173 // HideOverlay()) so that it can change its mind.
1116 if (height == 0) { 1174 if (height == 0) {
1117 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); 1175 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT);
1118 return; 1176 return;
1119 } 1177 }
1120 1178
1121 // If the preview is being shown for the first time since the user started 1179 // If the preview is being shown for the first time since the user started
1122 // typing, record a histogram value. 1180 // typing, record a histogram value.
1123 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { 1181 if (!first_interaction_time_.is_null() && model_.mode().is_default()) {
1124 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; 1182 base::TimeDelta delta = base::Time::Now() - first_interaction_time_;
1125 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); 1183 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta);
1126 } 1184 }
1127 1185
1128 // Show at 100% height except in the following cases: 1186 // Show at 100% height except in the following cases:
1129 // - The local omnibox popup is being loaded. 1187 // - The local omnibox popup is being loaded.
1130 // - Instant is disabled. The page needs to be able to show only a dropdown. 1188 // - Instant is disabled. The page needs to be able to show only a dropdown.
1131 // - The page wants to show custom NTP content. 1189 // - The page wants to show custom NTP content.
1132 // - The page is over a website other than search or an NTP, and is not 1190 // - The page is over a website other than search or an NTP, and is not
1133 // already showing at 100% height. 1191 // already showing at 100% height.
1134 if (loader_->IsUsingLocalPreview() || !instant_enabled_ || 1192 if (overlay_->IsUsingLocalPreview() || !instant_enabled_ ||
1135 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || 1193 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT ||
1136 (search_mode_.is_origin_default() && !IsFullHeight(model_))) 1194 (search_mode_.is_origin_default() && !IsFullHeight(model_)))
1137 model_.SetPreviewState(search_mode_, height, units); 1195 model_.SetPreviewState(search_mode_, height, units);
1138 else 1196 else
1139 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); 1197 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT);
1140 1198
1141 // If the user clicked on a query suggestion, also go ahead and commit the 1199 // 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 1200 // overlay. This is necessary because if the overlay was partially visible
1143 // when the suggestion was clicked, the click itself would not commit the 1201 // when the suggestion was clicked, the click itself would not commit the
1144 // overlay (because we're not full height). 1202 // overlay (because we're not full height).
1145 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) 1203 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION)
1146 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); 1204 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION);
1147 } 1205 }
1148 1206
1149 void InstantController::SendPopupBoundsToPage() { 1207 void InstantController::SendPopupBoundsToPage() {
1150 if (last_popup_bounds_ == popup_bounds_ || !loader_ || 1208 if (last_popup_bounds_ == popup_bounds_ || !overlay_ ||
1151 loader_->is_pointer_down_from_activate()) 1209 overlay_->is_pointer_down_from_activate())
1152 return; 1210 return;
1153 1211
1154 last_popup_bounds_ = popup_bounds_; 1212 last_popup_bounds_ = popup_bounds_;
1155 gfx::Rect preview_bounds = browser_->GetInstantBounds(); 1213 gfx::Rect preview_bounds = browser_->GetInstantBounds();
1156 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); 1214 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds);
1157 1215
1158 // Translate into window coordinates. 1216 // Translate into window coordinates.
1159 if (!intersection.IsEmpty()) { 1217 if (!intersection.IsEmpty()) {
1160 intersection.Offset(-preview_bounds.origin().x(), 1218 intersection.Offset(-preview_bounds.origin().x(),
1161 -preview_bounds.origin().y()); 1219 -preview_bounds.origin().y());
1162 } 1220 }
1163 1221
1164 // In the current Chrome UI, these must always be true so they sanity check 1222 // 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. 1223 // 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 1224 // 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 1225 // 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). 1226 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds).
1169 DCHECK_LE(0, intersection.x()); 1227 DCHECK_LE(0, intersection.x());
1170 DCHECK_LE(0, intersection.width()); 1228 DCHECK_LE(0, intersection.width());
1171 DCHECK_LE(0, intersection.height()); 1229 DCHECK_LE(0, intersection.height());
1172 1230
1173 loader_->SetPopupBounds(intersection); 1231 overlay_->SetPopupBounds(intersection);
1174 } 1232 }
1175 1233
1176 bool InstantController::GetInstantURL(const content::WebContents* active_tab, 1234 bool InstantController::GetInstantURL(Profile* profile,
1177 std::string* instant_url) const { 1235 std::string* instant_url) const {
1178 DCHECK(active_tab); 1236 DCHECK(profile);
1179 instant_url->clear(); 1237 instant_url->clear();
1180 1238
1181 if (extended_enabled_ && use_local_preview_only_) { 1239 if (extended_enabled_ && use_local_preview_only_) {
1182 *instant_url = kLocalOmniboxPopupURL; 1240 *instant_url = kLocalOmniboxPopupURL;
1183 return true; 1241 return true;
1184 } 1242 }
1185 1243
1186 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( 1244 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
1187 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> 1245 profile)->GetDefaultSearchProvider();
1188 GetDefaultSearchProvider();
1189 1246
1190 if (!template_url) { 1247 if (!template_url) {
1191 LOG_INSTANT_DEBUG_EVENT(this, "GetInstantURL: No template URL"); 1248 LOG_INSTANT_DEBUG_EVENT(this, "GetInstantURL: No template URL");
1192 return false; 1249 return false;
1193 } 1250 }
1194 1251
1195 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1252 CommandLine* command_line = CommandLine::ForCurrentProcess();
1196 if (command_line->HasSwitch(switches::kInstantURL)) 1253 if (command_line->HasSwitch(switches::kInstantURL))
1197 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); 1254 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL);
1198 1255
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 iter->second > kMaxInstantSupportFailures) { 1314 iter->second > kMaxInstantSupportFailures) {
1258 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); 1315 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST);
1259 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf( 1316 LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
1260 "GetInstantURL: Instant URL blacklisted: url=%s", 1317 "GetInstantURL: Instant URL blacklisted: url=%s",
1261 instant_url->c_str())); 1318 instant_url->c_str()));
1262 return false; 1319 return false;
1263 } 1320 }
1264 1321
1265 return true; 1322 return true;
1266 } 1323 }
1324
1325 void InstantController::BlacklistAndResetNTP() {
1326 ++blacklisted_urls_[ntp_->instant_url()];
1327 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
1328 ignore_result(ntp_->ReleaseContents());
1329 MessageLoop::current()->DeleteSoon(FROM_HERE, ntp_.release());
1330 ResetNTP();
1331 }
1332
1333 void InstantController::BlacklistAndResetOverlay() {
1334 ++blacklisted_urls_[overlay_->instant_url()];
1335 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_ADDED_TO_BLACKLIST);
1336 HideInternal();
1337 ignore_result(overlay_->ReleaseContents());
1338 MessageLoop::current()->DeleteSoon(FROM_HERE, overlay_.release());
1339 EnsureOverlayIsCurrent();
1340 }
1341
1342 void InstantController::RemoveFromBlacklist(const std::string& url) {
1343 if (blacklisted_urls_.erase(url)) {
1344 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_REMOVED_FROM_BLACKLIST);
1345 }
1346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698