[email protected] | f0dc7523 | 2012-01-05 01:07:00 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 5 | #include "chrome/browser/instant/instant_controller.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 6 | |
[email protected] | c90388e3 | 2011-11-29 02:18:47 | [diff] [blame] | 7 | #include "base/bind.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 8 | #include "base/command_line.h" |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 9 | #include "base/message_loop.h" |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 10 | #include "base/metrics/histogram.h" |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 11 | #include "base/rand_util.h" |
[email protected] | b3841c50 | 2011-03-09 01:21:31 | [diff] [blame] | 12 | #include "build/build_config.h" |
[email protected] | 9ac4009 | 2010-10-27 23:05:26 | [diff] [blame] | 13 | #include "chrome/browser/autocomplete/autocomplete_match.h" |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 14 | #include "chrome/browser/instant/instant_delegate.h" |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 15 | #include "chrome/browser/instant/instant_field_trial.h" |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 16 | #include "chrome/browser/instant/instant_loader.h" |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 17 | #include "chrome/browser/platform_util.h" |
[email protected] | 018cbb2 | 2010-10-11 22:32:09 | [diff] [blame] | 18 | #include "chrome/browser/prefs/pref_service.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 19 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 20 | #include "chrome/browser/search_engines/template_url.h" |
[email protected] | 8e5c89a | 2011-06-07 18:13:33 | [diff] [blame] | 21 | #include "chrome/browser/search_engines/template_url_service.h" |
| 22 | #include "chrome/browser/search_engines/template_url_service_factory.h" |
[email protected] | e7cfdbd | 2011-04-22 14:41:37 | [diff] [blame] | 23 | #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" |
[email protected] | 6a3ec231 | 2010-12-02 19:30:19 | [diff] [blame] | 24 | #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 25 | #include "chrome/common/chrome_notification_types.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 26 | #include "chrome/common/chrome_switches.h" |
[email protected] | 018cbb2 | 2010-10-11 22:32:09 | [diff] [blame] | 27 | #include "chrome/common/pref_names.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 28 | #include "content/public/browser/notification_service.h" |
[email protected] | 5626b089 | 2012-02-20 14:46:58 | [diff] [blame] | 29 | #include "content/public/browser/render_widget_host_view.h" |
[email protected] | ef9572e | 2012-01-04 22:14:12 | [diff] [blame] | 30 | #include "content/public/browser/web_contents.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 31 | |
[email protected] | 6eb8ea9 | 2011-08-22 21:01:41 | [diff] [blame] | 32 | #if defined(TOOLKIT_VIEWS) |
[email protected] | 477ae05 | 2011-11-18 23:53:57 | [diff] [blame] | 33 | #include "ui/views/focus/focus_manager.h" |
[email protected] | 5025f86 | 2011-11-30 23:35:20 | [diff] [blame] | 34 | #include "ui/views/view.h" |
[email protected] | c13be0d | 2011-11-22 02:09:58 | [diff] [blame] | 35 | #include "ui/views/widget/widget.h" |
[email protected] | 6eb8ea9 | 2011-08-22 21:01:41 | [diff] [blame] | 36 | #endif |
| 37 | |
[email protected] | fdf773c5 | 2010-11-01 20:58:19 | [diff] [blame] | 38 | InstantController::InstantController(Profile* profile, |
| 39 | InstantDelegate* delegate) |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 40 | : delegate_(delegate), |
[email protected] | d8e73bd | 2012-03-14 16:30:52 | [diff] [blame] | 41 | template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)), |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 42 | tab_contents_(NULL), |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 43 | is_displayable_(false), |
[email protected] | 3e48128 | 2011-10-15 15:39:50 | [diff] [blame] | 44 | is_out_of_date_(true), |
[email protected] | 484ae591 | 2010-09-29 19:16:14 | [diff] [blame] | 45 | commit_on_mouse_up_(false), |
[email protected] | 2905f74 | 2011-10-13 03:51:58 | [diff] [blame] | 46 | last_transition_type_(content::PAGE_TRANSITION_LINK), |
[email protected] | c90388e3 | 2011-11-29 02:18:47 | [diff] [blame] | 47 | ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
[email protected] | d8e73bd | 2012-03-14 16:30:52 | [diff] [blame] | 48 | DCHECK(template_url_service_); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 49 | PrefService* service = profile->GetPrefs(); |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 50 | if (service && !InstantFieldTrial::IsInstantExperiment(profile)) { |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 51 | // kInstantEnabledOnce was added after instant, set it now to make sure it |
| 52 | // is correctly set. |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 53 | service->SetBoolean(prefs::kInstantEnabledOnce, true); |
| 54 | } |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 55 | } |
| 56 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 57 | InstantController::~InstantController() { |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 58 | } |
| 59 | |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 60 | // static |
| 61 | void InstantController::RegisterUserPrefs(PrefService* prefs) { |
[email protected] | d36f941b | 2011-05-09 06:19:16 | [diff] [blame] | 62 | prefs->RegisterBooleanPref(prefs::kInstantConfirmDialogShown, |
| 63 | false, |
[email protected] | 18c2ffac | 2011-09-16 21:07:29 | [diff] [blame] | 64 | PrefService::SYNCABLE_PREF); |
[email protected] | d36f941b | 2011-05-09 06:19:16 | [diff] [blame] | 65 | prefs->RegisterBooleanPref(prefs::kInstantEnabled, |
| 66 | false, |
[email protected] | 18c2ffac | 2011-09-16 21:07:29 | [diff] [blame] | 67 | PrefService::SYNCABLE_PREF); |
[email protected] | d36f941b | 2011-05-09 06:19:16 | [diff] [blame] | 68 | prefs->RegisterBooleanPref(prefs::kInstantEnabledOnce, |
| 69 | false, |
[email protected] | 18c2ffac | 2011-09-16 21:07:29 | [diff] [blame] | 70 | PrefService::SYNCABLE_PREF); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | // static |
| 74 | void InstantController::RecordMetrics(Profile* profile) { |
[email protected] | 0c9d6bb1 | 2012-04-02 22:11:37 | [diff] [blame] | 75 | UMA_HISTOGRAM_ENUMERATION("Instant.Status", IsEnabled(profile), 2); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | // static |
| 79 | bool InstantController::IsEnabled(Profile* profile) { |
[email protected] | 6eff939 | 2011-01-26 21:46:50 | [diff] [blame] | 80 | PrefService* prefs = profile->GetPrefs(); |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 81 | return prefs->GetBoolean(prefs::kInstantEnabled) || |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 82 | InstantFieldTrial::IsInstantExperiment(profile); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | // static |
| 86 | void InstantController::Enable(Profile* profile) { |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 87 | PrefService* service = profile->GetPrefs(); |
| 88 | if (!service) |
| 89 | return; |
| 90 | |
[email protected] | ddb3be7 | 2012-03-31 00:50:13 | [diff] [blame] | 91 | base::Histogram* histogram = base::LinearHistogram::FactoryGet( |
| 92 | "Instant.Preference" + InstantFieldTrial::GetGroupName(profile), 1, 2, 3, |
| 93 | base::Histogram::kUmaTargetedHistogramFlag); |
| 94 | histogram->Add(1); |
| 95 | |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 96 | service->SetBoolean(prefs::kInstantEnabledOnce, true); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 97 | service->SetBoolean(prefs::kInstantEnabled, true); |
| 98 | service->SetBoolean(prefs::kInstantConfirmDialogShown, true); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | // static |
| 102 | void InstantController::Disable(Profile* profile) { |
| 103 | PrefService* service = profile->GetPrefs(); |
[email protected] | bfc031f | 2010-11-29 21:39:57 | [diff] [blame] | 104 | if (!service || !IsEnabled(profile)) |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 105 | return; |
| 106 | |
[email protected] | ddb3be7 | 2012-03-31 00:50:13 | [diff] [blame] | 107 | base::Histogram* histogram = base::LinearHistogram::FactoryGet( |
| 108 | "Instant.Preference" + InstantFieldTrial::GetGroupName(profile), 1, 2, 3, |
| 109 | base::Histogram::kUmaTargetedHistogramFlag); |
| 110 | histogram->Add(0); |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 111 | |
[email protected] | 849c9631 | 2011-07-26 01:06:57 | [diff] [blame] | 112 | service->SetBoolean(prefs::kInstantEnabledOnce, true); |
[email protected] | bfc031f | 2010-11-29 21:39:57 | [diff] [blame] | 113 | service->SetBoolean(prefs::kInstantEnabled, false); |
[email protected] | 7e03e81 | 2010-11-15 23:01:01 | [diff] [blame] | 114 | } |
| 115 | |
[email protected] | 939e54a | 2010-12-18 02:42:07 | [diff] [blame] | 116 | // static |
| 117 | bool InstantController::CommitIfCurrent(InstantController* controller) { |
| 118 | if (controller && controller->IsCurrent()) { |
| 119 | controller->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER); |
| 120 | return true; |
| 121 | } |
| 122 | return false; |
| 123 | } |
| 124 | |
[email protected] | 65d68da | 2011-09-08 03:19:33 | [diff] [blame] | 125 | bool InstantController::Update(TabContentsWrapper* tab_contents, |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 126 | const AutocompleteMatch& match, |
| 127 | const string16& user_text, |
[email protected] | 57ad7b8c | 2010-11-18 19:13:49 | [diff] [blame] | 128 | bool verbatim, |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 129 | string16* suggested_text) { |
[email protected] | bdf1d86 | 2010-11-24 02:46:11 | [diff] [blame] | 130 | suggested_text->clear(); |
| 131 | |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 132 | tab_contents_ = tab_contents; |
[email protected] | 484ae591 | 2010-09-29 19:16:14 | [diff] [blame] | 133 | commit_on_mouse_up_ = false; |
[email protected] | 97b6c4f | 2010-09-27 19:31:26 | [diff] [blame] | 134 | last_transition_type_ = match.transition; |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 135 | last_url_ = match.destination_url; |
| 136 | last_user_text_ = user_text; |
| 137 | |
[email protected] | d8e73bd | 2012-03-14 16:30:52 | [diff] [blame] | 138 | const TemplateURL* template_url = match.GetTemplateURL(); |
| 139 | const TemplateURL* default_t_url = |
| 140 | template_url_service_->GetDefaultSearchProvider(); |
| 141 | if (!IsValidInstantTemplateURL(template_url) || !default_t_url || |
| 142 | (template_url->id() != default_t_url->id())) { |
[email protected] | 3e48128 | 2011-10-15 15:39:50 | [diff] [blame] | 143 | Hide(); |
[email protected] | 65d68da | 2011-09-08 03:19:33 | [diff] [blame] | 144 | return false; |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 145 | } |
| 146 | |
[email protected] | f0dc7523 | 2012-01-05 01:07:00 | [diff] [blame] | 147 | if (!loader_.get()) { |
| 148 | loader_.reset(new InstantLoader(this, template_url->id(), |
| 149 | InstantFieldTrial::GetGroupName(tab_contents->profile()))); |
| 150 | } |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 151 | |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 152 | // In some rare cases (involving group policy), Instant can go from the field |
[email protected] | 45051c3 | 2011-10-18 05:28:45 | [diff] [blame] | 153 | // trial to normal mode, with no intervening call to DestroyPreviewContents(). |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 154 | // This would leave the loader in a weird state, which would manifest if the |
| 155 | // user pressed <Enter> without calling Update(). TODO(sreeram): Handle it. |
[email protected] | f679716 | 2011-10-25 03:11:31 | [diff] [blame] | 156 | if (InstantFieldTrial::IsSilentExperiment(tab_contents->profile())) { |
| 157 | // For the SILENT field trial we process |user_text| at commit time, which |
[email protected] | 3e48128 | 2011-10-15 15:39:50 | [diff] [blame] | 158 | // means we're never really out of date. |
| 159 | is_out_of_date_ = false; |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 160 | loader_->MaybeLoadInstantURL(tab_contents, template_url); |
| 161 | return true; |
| 162 | } |
[email protected] | 36d5e559 | 2010-11-15 20:45:59 | [diff] [blame] | 163 | |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 164 | UpdateLoader(template_url, match.destination_url, match.transition, user_text, |
| 165 | verbatim, suggested_text); |
[email protected] | eac60f7 | 2010-10-21 19:11:39 | [diff] [blame] | 166 | |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 167 | content::NotificationService::current()->Notify( |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 168 | chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 169 | content::Source<InstantController>(this), |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 170 | content::NotificationService::NoDetails()); |
[email protected] | 65d68da | 2011-09-08 03:19:33 | [diff] [blame] | 171 | return true; |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 172 | } |
| 173 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 174 | void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) { |
[email protected] | 46fe8e9 | 2010-09-22 03:32:47 | [diff] [blame] | 175 | if (omnibox_bounds_ == bounds) |
| 176 | return; |
| 177 | |
[email protected] | 6e6b59f4 | 2010-12-13 20:20:23 | [diff] [blame] | 178 | // Always track the omnibox bounds. That way if Update is later invoked the |
| 179 | // bounds are in sync. |
| 180 | omnibox_bounds_ = bounds; |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 181 | |
| 182 | if (loader_.get() && !is_out_of_date_ && |
| 183 | !InstantFieldTrial::IsHiddenExperiment(tab_contents_->profile())) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 184 | loader_->SetOmniboxBounds(bounds); |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 185 | } |
[email protected] | 46fe8e9 | 2010-09-22 03:32:47 | [diff] [blame] | 186 | } |
| 187 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 188 | void InstantController::DestroyPreviewContents() { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 189 | if (!loader_.get()) { |
[email protected] | 1733651 | 2010-09-22 17:28:27 | [diff] [blame] | 190 | // We're not showing anything, nothing to do. |
| 191 | return; |
| 192 | } |
| 193 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 194 | delegate_->HideInstant(); |
[email protected] | 5419ff9 | 2012-01-06 21:17:15 | [diff] [blame] | 195 | delete ReleasePreviewContents(INSTANT_COMMIT_DESTROY, NULL); |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 196 | } |
| 197 | |
[email protected] | 3e48128 | 2011-10-15 15:39:50 | [diff] [blame] | 198 | void InstantController::Hide() { |
| 199 | is_out_of_date_ = true; |
[email protected] | 7cce9f2 | 2011-02-28 22:02:47 | [diff] [blame] | 200 | commit_on_mouse_up_ = false; |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 201 | if (is_displayable_) { |
| 202 | is_displayable_ = false; |
[email protected] | 2573b8d | 2011-03-01 16:20:36 | [diff] [blame] | 203 | delegate_->HideInstant(); |
| 204 | } |
[email protected] | 7cce9f2 | 2011-02-28 22:02:47 | [diff] [blame] | 205 | } |
| 206 | |
[email protected] | eadbf953 | 2011-11-03 23:52:16 | [diff] [blame] | 207 | bool InstantController::IsCurrent() const { |
[email protected] | 5376c26 | 2011-09-01 04:53:19 | [diff] [blame] | 208 | // TODO(mmenke): See if we can do something more intelligent in the |
| 209 | // navigation pending case. |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 210 | return is_displayable_ && !loader_->IsNavigationPending() && |
| 211 | !loader_->needs_reload(); |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 212 | } |
| 213 | |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 214 | bool InstantController::PrepareForCommit() { |
[email protected] | 07c4ce7 | 2011-10-18 17:08:20 | [diff] [blame] | 215 | // Basic checks to prevent accessing a dangling |tab_contents_| pointer. |
| 216 | // http://crbug.com/100521. |
| 217 | if (is_out_of_date_ || !loader_.get()) |
| 218 | return false; |
| 219 | |
[email protected] | f679716 | 2011-10-25 03:11:31 | [diff] [blame] | 220 | // If we are not in the HIDDEN or SILENT field trials, return the status of |
| 221 | // the preview. |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 222 | if (!InstantFieldTrial::IsHiddenExperiment(tab_contents_->profile())) |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 223 | return IsCurrent(); |
| 224 | |
[email protected] | d8e73bd | 2012-03-14 16:30:52 | [diff] [blame] | 225 | const TemplateURL* template_url = |
| 226 | template_url_service_->GetDefaultSearchProvider(); |
[email protected] | 07c4ce7 | 2011-10-18 17:08:20 | [diff] [blame] | 227 | if (!IsValidInstantTemplateURL(template_url) || |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 228 | loader_->template_url_id() != template_url->id() || |
| 229 | loader_->IsNavigationPending() || |
| 230 | loader_->is_determining_if_page_supports_instant()) { |
| 231 | return false; |
| 232 | } |
| 233 | |
[email protected] | d6909df | 2012-01-25 01:46:35 | [diff] [blame] | 234 | // In the HIDDEN and SUGGEST experiments (but not SILENT), we must have sent |
| 235 | // an Update() by now, so check if the loader failed to process it. |
| 236 | if (!InstantFieldTrial::IsSilentExperiment(tab_contents_->profile()) && |
| 237 | (!loader_->ready() || !loader_->http_status_ok())) { |
| 238 | return false; |
| 239 | } |
| 240 | |
[email protected] | 64f09b8 | 2011-10-13 16:17:20 | [diff] [blame] | 241 | // Ignore the suggested text, as we are about to commit the verbatim query. |
| 242 | string16 suggested_text; |
| 243 | UpdateLoader(template_url, last_url_, last_transition_type_, last_user_text_, |
| 244 | true, &suggested_text); |
| 245 | return true; |
| 246 | } |
| 247 | |
[email protected] | 094b052 | 2011-10-06 00:55:27 | [diff] [blame] | 248 | TabContentsWrapper* InstantController::CommitCurrentPreview( |
| 249 | InstantCommitType type) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 250 | DCHECK(loader_.get()); |
[email protected] | 5419ff9 | 2012-01-06 21:17:15 | [diff] [blame] | 251 | TabContentsWrapper* tab = ReleasePreviewContents(type, tab_contents_); |
[email protected] | ef9572e | 2012-01-04 22:14:12 | [diff] [blame] | 252 | tab->web_contents()->GetController().CopyStateFromAndPrune( |
| 253 | &tab_contents_->web_contents()->GetController()); |
[email protected] | c65e2f15 | 2010-10-14 15:30:40 | [diff] [blame] | 254 | delegate_->CommitInstant(tab); |
[email protected] | e7cfdbd | 2011-04-22 14:41:37 | [diff] [blame] | 255 | CompleteRelease(tab); |
[email protected] | 094b052 | 2011-10-06 00:55:27 | [diff] [blame] | 256 | return tab; |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 257 | } |
| 258 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 259 | void InstantController::SetCommitOnMouseUp() { |
[email protected] | 484ae591 | 2010-09-29 19:16:14 | [diff] [blame] | 260 | commit_on_mouse_up_ = true; |
| 261 | } |
| 262 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 263 | bool InstantController::IsMouseDownFromActivate() { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 264 | DCHECK(loader_.get()); |
| 265 | return loader_->IsMouseDownFromActivate(); |
[email protected] | 484ae591 | 2010-09-29 19:16:14 | [diff] [blame] | 266 | } |
| 267 | |
[email protected] | 20ac3c3 | 2011-03-06 17:59:19 | [diff] [blame] | 268 | #if defined(OS_MACOSX) |
| 269 | void InstantController::OnAutocompleteLostFocus( |
| 270 | gfx::NativeView view_gaining_focus) { |
| 271 | // If |IsMouseDownFromActivate()| returns false, the RenderWidgetHostView did |
| 272 | // not receive a mouseDown event. Therefore, we should destroy the preview. |
| 273 | // Otherwise, the RWHV was clicked, so we commit the preview. |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 274 | if (!IsCurrent() || !IsMouseDownFromActivate()) |
[email protected] | 20ac3c3 | 2011-03-06 17:59:19 | [diff] [blame] | 275 | DestroyPreviewContents(); |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 276 | else |
[email protected] | 20ac3c3 | 2011-03-06 17:59:19 | [diff] [blame] | 277 | SetCommitOnMouseUp(); |
[email protected] | 20ac3c3 | 2011-03-06 17:59:19 | [diff] [blame] | 278 | } |
| 279 | #else |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 280 | void InstantController::OnAutocompleteLostFocus( |
| 281 | gfx::NativeView view_gaining_focus) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 282 | if (!IsCurrent()) { |
[email protected] | 1946c93 | 2010-12-15 00:07:38 | [diff] [blame] | 283 | DestroyPreviewContents(); |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 284 | return; |
[email protected] | 1946c93 | 2010-12-15 00:07:38 | [diff] [blame] | 285 | } |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 286 | |
[email protected] | 5626b089 | 2012-02-20 14:46:58 | [diff] [blame] | 287 | content::RenderWidgetHostView* rwhv = |
[email protected] | ef9572e | 2012-01-04 22:14:12 | [diff] [blame] | 288 | GetPreviewContents()->web_contents()->GetRenderWidgetHostView(); |
[email protected] | 5a85751b | 2010-11-17 01:33:27 | [diff] [blame] | 289 | if (!view_gaining_focus || !rwhv) { |
| 290 | DestroyPreviewContents(); |
| 291 | return; |
| 292 | } |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 293 | |
[email protected] | 6eb8ea9 | 2011-08-22 21:01:41 | [diff] [blame] | 294 | #if defined(TOOLKIT_VIEWS) |
| 295 | // For views the top level widget is always focused. If the focus change |
| 296 | // originated in views determine the child Widget from the view that is being |
| 297 | // focused. |
[email protected] | 09c6943 | 2012-03-16 16:23:28 | [diff] [blame] | 298 | views::Widget* widget = |
| 299 | views::Widget::GetWidgetForNativeView(view_gaining_focus); |
| 300 | if (widget) { |
| 301 | views::FocusManager* focus_manager = widget->GetFocusManager(); |
| 302 | if (focus_manager && focus_manager->is_changing_focus() && |
| 303 | focus_manager->GetFocusedView() && |
| 304 | focus_manager->GetFocusedView()->GetWidget()) { |
| 305 | view_gaining_focus = |
| 306 | focus_manager->GetFocusedView()->GetWidget()->GetNativeView(); |
[email protected] | 6eb8ea9 | 2011-08-22 21:01:41 | [diff] [blame] | 307 | } |
| 308 | } |
| 309 | #endif |
| 310 | |
[email protected] | 3c9e187 | 2010-11-18 16:17:49 | [diff] [blame] | 311 | gfx::NativeView tab_view = |
[email protected] | ef9572e | 2012-01-04 22:14:12 | [diff] [blame] | 312 | GetPreviewContents()->web_contents()->GetNativeView(); |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 313 | // Focus is going to the renderer. |
| 314 | if (rwhv->GetNativeView() == view_gaining_focus || |
| 315 | tab_view == view_gaining_focus) { |
| 316 | if (!IsMouseDownFromActivate()) { |
| 317 | // If the mouse is not down, focus is not going to the renderer. Someone |
| 318 | // else moved focus and we shouldn't commit. |
[email protected] | 5a85751b | 2010-11-17 01:33:27 | [diff] [blame] | 319 | DestroyPreviewContents(); |
| 320 | return; |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 321 | } |
| 322 | |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 323 | // We're showing instant results. As instant results may shift when |
| 324 | // committing we commit on the mouse up. This way a slow click still works |
| 325 | // fine. |
| 326 | SetCommitOnMouseUp(); |
[email protected] | 5a85751b | 2010-11-17 01:33:27 | [diff] [blame] | 327 | return; |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 328 | } |
| 329 | |
| 330 | // Walk up the view hierarchy. If the view gaining focus is a subview of the |
[email protected] | 0932b30c | 2012-04-17 13:25:10 | [diff] [blame^] | 331 | // WebContents view (such as a windowed plugin or http auth dialog), we want |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 332 | // to keep the preview contents. Otherwise, focus has gone somewhere else, |
| 333 | // such as the JS inspector, and we want to cancel the preview. |
| 334 | gfx::NativeView view_gaining_focus_ancestor = view_gaining_focus; |
| 335 | while (view_gaining_focus_ancestor && |
| 336 | view_gaining_focus_ancestor != tab_view) { |
| 337 | view_gaining_focus_ancestor = |
| 338 | platform_util::GetParent(view_gaining_focus_ancestor); |
| 339 | } |
| 340 | |
[email protected] | 5a85751b | 2010-11-17 01:33:27 | [diff] [blame] | 341 | if (view_gaining_focus_ancestor) { |
| 342 | CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); |
| 343 | return; |
| 344 | } |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 345 | |
[email protected] | 5a85751b | 2010-11-17 01:33:27 | [diff] [blame] | 346 | DestroyPreviewContents(); |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 347 | } |
[email protected] | 20ac3c3 | 2011-03-06 17:59:19 | [diff] [blame] | 348 | #endif |
[email protected] | ba6680f | 2010-11-01 20:35:08 | [diff] [blame] | 349 | |
[email protected] | f2557bd | 2011-06-01 02:33:07 | [diff] [blame] | 350 | void InstantController::OnAutocompleteGotFocus( |
| 351 | TabContentsWrapper* tab_contents) { |
| 352 | CommandLine* cl = CommandLine::ForCurrentProcess(); |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 353 | if (!cl->HasSwitch(switches::kPreloadInstantSearch) && |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 354 | !InstantFieldTrial::IsInstantExperiment(tab_contents->profile())) { |
[email protected] | f2557bd | 2011-06-01 02:33:07 | [diff] [blame] | 355 | return; |
[email protected] | 2380b9a | 2011-07-28 20:10:36 | [diff] [blame] | 356 | } |
[email protected] | f2557bd | 2011-06-01 02:33:07 | [diff] [blame] | 357 | |
[email protected] | d8e73bd | 2012-03-14 16:30:52 | [diff] [blame] | 358 | const TemplateURL* template_url = |
| 359 | template_url_service_->GetDefaultSearchProvider(); |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 360 | if (!IsValidInstantTemplateURL(template_url)) |
[email protected] | f2557bd | 2011-06-01 02:33:07 | [diff] [blame] | 361 | return; |
| 362 | |
[email protected] | f2557bd | 2011-06-01 02:33:07 | [diff] [blame] | 363 | tab_contents_ = tab_contents; |
| 364 | |
[email protected] | f0dc7523 | 2012-01-05 01:07:00 | [diff] [blame] | 365 | if (!loader_.get()) { |
| 366 | loader_.reset(new InstantLoader(this, template_url->id(), |
| 367 | InstantFieldTrial::GetGroupName(tab_contents->profile()))); |
| 368 | } |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 369 | loader_->MaybeLoadInstantURL(tab_contents, template_url); |
[email protected] | f2557bd | 2011-06-01 02:33:07 | [diff] [blame] | 370 | } |
| 371 | |
[email protected] | 3c9e187 | 2010-11-18 16:17:49 | [diff] [blame] | 372 | TabContentsWrapper* InstantController::ReleasePreviewContents( |
[email protected] | 5419ff9 | 2012-01-06 21:17:15 | [diff] [blame] | 373 | InstantCommitType type, |
| 374 | TabContentsWrapper* current_tab) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 375 | if (!loader_.get()) |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame] | 376 | return NULL; |
| 377 | |
[email protected] | 5419ff9 | 2012-01-06 21:17:15 | [diff] [blame] | 378 | TabContentsWrapper* tab = loader_->ReleasePreviewContents(type, current_tab); |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 379 | ClearBlacklist(); |
[email protected] | 07c4ce7 | 2011-10-18 17:08:20 | [diff] [blame] | 380 | is_out_of_date_ = true; |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 381 | is_displayable_ = false; |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 382 | commit_on_mouse_up_ = false; |
[email protected] | 1946c93 | 2010-12-15 00:07:38 | [diff] [blame] | 383 | omnibox_bounds_ = gfx::Rect(); |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 384 | loader_.reset(); |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 385 | return tab; |
| 386 | } |
| 387 | |
[email protected] | e7cfdbd | 2011-04-22 14:41:37 | [diff] [blame] | 388 | void InstantController::CompleteRelease(TabContentsWrapper* tab) { |
| 389 | tab->blocked_content_tab_helper()->SetAllContentsBlocked(false); |
[email protected] | c65e2f15 | 2010-10-14 15:30:40 | [diff] [blame] | 390 | } |
| 391 | |
[email protected] | eadbf953 | 2011-11-03 23:52:16 | [diff] [blame] | 392 | TabContentsWrapper* InstantController::GetPreviewContents() const { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 393 | return loader_.get() ? loader_->preview_contents() : NULL; |
[email protected] | a5ec3ea | 2011-02-09 17:01:28 | [diff] [blame] | 394 | } |
| 395 | |
[email protected] | 3d3afbf | 2011-03-29 19:59:21 | [diff] [blame] | 396 | void InstantController::InstantStatusChanged(InstantLoader* loader) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 397 | DCHECK(loader_.get()); |
| 398 | UpdateIsDisplayable(); |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 399 | } |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 400 | |
[email protected] | 33b8b8e | 2011-03-15 14:51:55 | [diff] [blame] | 401 | void InstantController::SetSuggestedTextFor( |
| 402 | InstantLoader* loader, |
| 403 | const string16& text, |
| 404 | InstantCompleteBehavior behavior) { |
[email protected] | f679716 | 2011-10-25 03:11:31 | [diff] [blame] | 405 | if (!is_out_of_date_ && |
[email protected] | e084b1b | 2011-11-17 06:52:44 | [diff] [blame] | 406 | InstantFieldTrial::ShouldSetSuggestedText(tab_contents_->profile())) { |
[email protected] | f679716 | 2011-10-25 03:11:31 | [diff] [blame] | 407 | delegate_->SetSuggestedText(text, behavior); |
| 408 | } |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 409 | } |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 410 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 411 | gfx::Rect InstantController::GetInstantBounds() { |
| 412 | return delegate_->GetInstantBounds(); |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 413 | } |
| 414 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 415 | bool InstantController::ShouldCommitInstantOnMouseUp() { |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 416 | return commit_on_mouse_up_; |
| 417 | } |
| 418 | |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 419 | void InstantController::CommitInstantLoader(InstantLoader* loader) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 420 | if (loader_.get() && loader_.get() == loader) { |
[email protected] | 6b723f8 | 2010-10-05 20:14:27 | [diff] [blame] | 421 | CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST); |
[email protected] | a0b8466 | 2010-10-04 23:22:04 | [diff] [blame] | 422 | } else { |
| 423 | // This can happen if the mouse was down, we swapped out the preview and |
| 424 | // the mouse was released. Generally this shouldn't happen, but if it does |
| 425 | // revert. |
| 426 | DestroyPreviewContents(); |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 427 | } |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 428 | } |
| 429 | |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 430 | void InstantController::InstantLoaderDoesntSupportInstant( |
[email protected] | 4c1b035d | 2010-12-10 02:32:23 | [diff] [blame] | 431 | InstantLoader* loader) { |
[email protected] | 1946c93 | 2010-12-15 00:07:38 | [diff] [blame] | 432 | VLOG(1) << "provider does not support instant"; |
[email protected] | 4c1b035d | 2010-12-10 02:32:23 | [diff] [blame] | 433 | |
| 434 | // Don't attempt to use instant for this search engine again. |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 435 | BlacklistFromInstant(); |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 436 | } |
| 437 | |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 438 | void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 439 | // Don't attempt to use instant for this search engine again. |
| 440 | BlacklistFromInstant(); |
[email protected] | 2573b8d | 2011-03-01 16:20:36 | [diff] [blame] | 441 | } |
| 442 | |
[email protected] | 00d6421 | 2011-05-25 18:18:28 | [diff] [blame] | 443 | void InstantController::SwappedTabContents(InstantLoader* loader) { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 444 | if (is_displayable_) |
| 445 | delegate_->ShowInstant(loader->preview_contents()); |
[email protected] | 00d6421 | 2011-05-25 18:18:28 | [diff] [blame] | 446 | } |
| 447 | |
[email protected] | 09c6943 | 2012-03-16 16:23:28 | [diff] [blame] | 448 | void InstantController::InstantLoaderContentsFocused() { |
| 449 | #if defined(USE_AURA) |
| 450 | // On aura the omnibox only receives a focus lost if we initiate the focus |
| 451 | // change. This does that. |
| 452 | if (!InstantFieldTrial::IsSilentExperiment(tab_contents_->profile())) |
| 453 | delegate_->InstantPreviewFocused(); |
| 454 | #endif |
| 455 | } |
| 456 | |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 457 | void InstantController::UpdateIsDisplayable() { |
[email protected] | f679716 | 2011-10-25 03:11:31 | [diff] [blame] | 458 | if (!is_out_of_date_ && |
| 459 | InstantFieldTrial::IsHiddenExperiment(tab_contents_->profile())) { |
| 460 | return; |
| 461 | } |
| 462 | |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 463 | bool displayable = |
[email protected] | 3e48128 | 2011-10-15 15:39:50 | [diff] [blame] | 464 | (!is_out_of_date_ && loader_.get() && loader_->ready() && |
| 465 | loader_->http_status_ok()); |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 466 | if (displayable == is_displayable_) |
[email protected] | 2573b8d | 2011-03-01 16:20:36 | [diff] [blame] | 467 | return; |
| 468 | |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 469 | is_displayable_ = displayable; |
| 470 | if (!is_displayable_) { |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 471 | delegate_->HideInstant(); |
[email protected] | 2573b8d | 2011-03-01 16:20:36 | [diff] [blame] | 472 | } else { |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 473 | delegate_->ShowInstant(loader_->preview_contents()); |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 474 | content::NotificationService::current()->Notify( |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 475 | chrome::NOTIFICATION_INSTANT_CONTROLLER_SHOWN, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 476 | content::Source<InstantController>(this), |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 477 | content::NotificationService::NoDetails()); |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 478 | } |
| 479 | } |
| 480 | |
[email protected] | 7c71e94 | 2010-10-14 18:18:59 | [diff] [blame] | 481 | void InstantController::UpdateLoader(const TemplateURL* template_url, |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 482 | const GURL& url, |
[email protected] | 2905f74 | 2011-10-13 03:51:58 | [diff] [blame] | 483 | content::PageTransition transition_type, |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 484 | const string16& user_text, |
[email protected] | 57ad7b8c | 2010-11-18 19:13:49 | [diff] [blame] | 485 | bool verbatim, |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 486 | string16* suggested_text) { |
[email protected] | 3e48128 | 2011-10-15 15:39:50 | [diff] [blame] | 487 | is_out_of_date_ = false; |
[email protected] | e084b1b | 2011-11-17 06:52:44 | [diff] [blame] | 488 | if (!InstantFieldTrial::IsHiddenExperiment(tab_contents_->profile())) |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 489 | loader_->SetOmniboxBounds(omnibox_bounds_); |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 490 | loader_->Update(tab_contents_, template_url, url, transition_type, user_text, |
| 491 | verbatim, suggested_text); |
| 492 | UpdateIsDisplayable(); |
[email protected] | 9963020 | 2011-10-28 21:49:06 | [diff] [blame] | 493 | // For the HIDDEN and SILENT field trials, don't send back suggestions. |
[email protected] | e084b1b | 2011-11-17 06:52:44 | [diff] [blame] | 494 | if (!InstantFieldTrial::ShouldSetSuggestedText(tab_contents_->profile())) |
[email protected] | f679716 | 2011-10-25 03:11:31 | [diff] [blame] | 495 | suggested_text->clear(); |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 496 | } |
| 497 | |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 498 | // Returns true if |template_url| is a valid TemplateURL for use by instant. |
| 499 | bool InstantController::IsValidInstantTemplateURL( |
| 500 | const TemplateURL* template_url) { |
[email protected] | 360ba05 | 2012-04-04 17:26:13 | [diff] [blame] | 501 | return template_url && template_url->id() && |
| 502 | template_url->instant_url_ref().SupportsReplacement() && |
[email protected] | 2b15fc8c | 2011-10-07 20:52:36 | [diff] [blame] | 503 | !IsBlacklistedFromInstant(template_url->id()); |
| 504 | } |
| 505 | |
| 506 | void InstantController::BlacklistFromInstant() { |
| 507 | if (!loader_.get()) |
| 508 | return; |
| 509 | |
| 510 | DCHECK(loader_->template_url_id()); |
| 511 | blacklisted_ids_.insert(loader_->template_url_id()); |
| 512 | |
| 513 | // Because of the state of the stack we can't destroy the loader now. |
| 514 | ScheduleDestroy(loader_.release()); |
| 515 | UpdateIsDisplayable(); |
[email protected] | 0a38747 | 2010-10-07 00:18:20 | [diff] [blame] | 516 | } |
| 517 | |
| 518 | bool InstantController::IsBlacklistedFromInstant(TemplateURLID id) { |
| 519 | return blacklisted_ids_.count(id) > 0; |
| 520 | } |
| 521 | |
| 522 | void InstantController::ClearBlacklist() { |
| 523 | blacklisted_ids_.clear(); |
| 524 | } |
[email protected] | 804d6c8f | 2010-10-08 02:49:50 | [diff] [blame] | 525 | |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 526 | void InstantController::ScheduleDestroy(InstantLoader* loader) { |
| 527 | loaders_to_destroy_.push_back(loader); |
[email protected] | c90388e3 | 2011-11-29 02:18:47 | [diff] [blame] | 528 | if (!weak_factory_.HasWeakPtrs()) { |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 529 | MessageLoop::current()->PostTask( |
[email protected] | c90388e3 | 2011-11-29 02:18:47 | [diff] [blame] | 530 | FROM_HERE, base::Bind(&InstantController::DestroyLoaders, |
| 531 | weak_factory_.GetWeakPtr())); |
[email protected] | f38adeeb | 2010-12-08 01:08:11 | [diff] [blame] | 532 | } |
| 533 | } |
| 534 | |
| 535 | void InstantController::DestroyLoaders() { |
| 536 | loaders_to_destroy_.reset(); |
| 537 | } |