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

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

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

Powered by Google App Engine
This is Rietveld 408576698