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

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

Powered by Google App Engine
This is Rietveld 408576698