OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/search/instant_service.h" | 5 #include "chrome/browser/search/instant_service.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 color.g = SkColorGetG(sKColor); | 60 color.g = SkColorGetG(sKColor); |
61 color.b = SkColorGetB(sKColor); | 61 color.b = SkColorGetB(sKColor); |
62 color.a = SkColorGetA(sKColor); | 62 color.a = SkColorGetA(sKColor); |
63 return color; | 63 return color; |
64 } | 64 } |
65 | 65 |
66 } // namespace | 66 } // namespace |
67 | 67 |
68 InstantService::InstantService(Profile* profile) | 68 InstantService::InstantService(Profile* profile) |
69 : profile_(profile), | 69 : profile_(profile), |
| 70 ntp_prerenderer_(profile, this, profile->GetPrefs()), |
| 71 browser_instant_controller_object_count_(0), |
70 weak_ptr_factory_(this) { | 72 weak_ptr_factory_(this) { |
71 // Stub for unit tests. | 73 // Stub for unit tests. |
72 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 74 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
73 return; | 75 return; |
74 | 76 |
75 ResetInstantSearchPrerenderer(); | 77 ResetInstantSearchPrerenderer(); |
76 | 78 |
77 registrar_.Add(this, | 79 registrar_.Add(this, |
78 content::NOTIFICATION_RENDERER_PROCESS_CREATED, | 80 content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
79 content::NotificationService::AllSources()); | 81 content::NotificationService::AllSources()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 content::URLDataSource::Add(profile_, new MostVisitedIframeSource()); | 117 content::URLDataSource::Add(profile_, new MostVisitedIframeSource()); |
116 | 118 |
117 profile_pref_registrar_.Init(profile_->GetPrefs()); | 119 profile_pref_registrar_.Init(profile_->GetPrefs()); |
118 profile_pref_registrar_.Add( | 120 profile_pref_registrar_.Add( |
119 prefs::kDefaultSearchProviderID, | 121 prefs::kDefaultSearchProviderID, |
120 base::Bind(&InstantService::OnDefaultSearchProviderChanged, | 122 base::Bind(&InstantService::OnDefaultSearchProviderChanged, |
121 base::Unretained(this))); | 123 base::Unretained(this))); |
122 | 124 |
123 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, | 125 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, |
124 content::Source<Profile>(profile_->GetOriginalProfile())); | 126 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 127 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 128 content::Source<Profile>(profile_)); |
125 } | 129 } |
126 | 130 |
127 InstantService::~InstantService() { | 131 InstantService::~InstantService() { |
128 } | 132 } |
129 | 133 |
130 void InstantService::AddInstantProcess(int process_id) { | 134 void InstantService::AddInstantProcess(int process_id) { |
131 process_ids_.insert(process_id); | 135 process_ids_.insert(process_id); |
132 | 136 |
133 if (instant_io_context_.get()) { | 137 if (instant_io_context_.get()) { |
134 BrowserThread::PostTask(BrowserThread::IO, | 138 BrowserThread::PostTask(BrowserThread::IO, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 if (instant_io_context_.get()) { | 198 if (instant_io_context_.get()) { |
195 BrowserThread::PostTask( | 199 BrowserThread::PostTask( |
196 BrowserThread::IO, | 200 BrowserThread::IO, |
197 FROM_HERE, | 201 FROM_HERE, |
198 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, | 202 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, |
199 instant_io_context_)); | 203 instant_io_context_)); |
200 } | 204 } |
201 instant_io_context_ = NULL; | 205 instant_io_context_ = NULL; |
202 } | 206 } |
203 | 207 |
| 208 scoped_ptr<content::WebContents> InstantService::ReleaseNTPContents() { |
| 209 return ntp_prerenderer_.ReleaseNTPContents(); |
| 210 } |
| 211 |
| 212 content::WebContents* InstantService::GetNTPContents() const { |
| 213 return ntp_prerenderer_.GetNTPContents(); |
| 214 } |
| 215 |
| 216 void InstantService::OnBrowserInstantControllerCreated() { |
| 217 if (profile_->IsOffTheRecord()) |
| 218 return; |
| 219 |
| 220 ++browser_instant_controller_object_count_; |
| 221 |
| 222 if (browser_instant_controller_object_count_ == 1) |
| 223 ntp_prerenderer_.ReloadInstantNTP(); |
| 224 } |
| 225 |
| 226 void InstantService::OnBrowserInstantControllerDestroyed() { |
| 227 if (profile_->IsOffTheRecord()) |
| 228 return; |
| 229 |
| 230 DCHECK_GT(browser_instant_controller_object_count_, 0U); |
| 231 --browser_instant_controller_object_count_; |
| 232 |
| 233 // All browser windows have closed, so release the InstantNTP resources to |
| 234 // work around http://crbug.com/180810. |
| 235 if (browser_instant_controller_object_count_ == 0) |
| 236 ntp_prerenderer_.DeleteNTPContents(); |
| 237 } |
| 238 |
204 void InstantService::Observe(int type, | 239 void InstantService::Observe(int type, |
205 const content::NotificationSource& source, | 240 const content::NotificationSource& source, |
206 const content::NotificationDetails& details) { | 241 const content::NotificationDetails& details) { |
207 switch (type) { | 242 switch (type) { |
208 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: | 243 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: |
209 SendSearchURLsToRenderer( | 244 SendSearchURLsToRenderer( |
210 content::Source<content::RenderProcessHost>(source).ptr()); | 245 content::Source<content::RenderProcessHost>(source).ptr()); |
211 break; | 246 break; |
212 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 247 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
213 OnRendererProcessTerminated( | 248 OnRendererProcessTerminated( |
214 content::Source<content::RenderProcessHost>(source)->GetID()); | 249 content::Source<content::RenderProcessHost>(source)->GetID()); |
215 break; | 250 break; |
216 case chrome::NOTIFICATION_TOP_SITES_CHANGED: { | 251 case chrome::NOTIFICATION_TOP_SITES_CHANGED: { |
217 history::TopSites* top_sites = profile_->GetTopSites(); | 252 history::TopSites* top_sites = profile_->GetTopSites(); |
218 if (top_sites) { | 253 if (top_sites) { |
219 top_sites->GetMostVisitedURLs( | 254 top_sites->GetMostVisitedURLs( |
220 base::Bind(&InstantService::OnMostVisitedItemsReceived, | 255 base::Bind(&InstantService::OnMostVisitedItemsReceived, |
221 weak_ptr_factory_.GetWeakPtr()), false); | 256 weak_ptr_factory_.GetWeakPtr()), false); |
222 } | 257 } |
223 break; | 258 break; |
224 } | 259 } |
225 #if defined(ENABLE_THEMES) | 260 #if defined(ENABLE_THEMES) |
226 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: { | 261 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: { |
227 OnThemeChanged(content::Source<ThemeService>(source).ptr()); | 262 OnThemeChanged(content::Source<ThemeService>(source).ptr()); |
228 break; | 263 break; |
229 } | 264 } |
230 #endif // defined(ENABLE_THEMES) | 265 #endif // defined(ENABLE_THEMES) |
| 266 case chrome::NOTIFICATION_PROFILE_DESTROYED: { |
| 267 // Last chance to delete InstantNTP contents. We generally delete |
| 268 // preloaded InstantNTP when the last BrowserInstantController object is |
| 269 // destroyed. When the browser shutdown happens without closing browsers, |
| 270 // there is a race condition between BrowserInstantController destruction |
| 271 // and Profile destruction. |
| 272 if (GetNTPContents()) |
| 273 ntp_prerenderer_.DeleteNTPContents(); |
| 274 break; |
| 275 } |
231 case chrome::NOTIFICATION_GOOGLE_URL_UPDATED: { | 276 case chrome::NOTIFICATION_GOOGLE_URL_UPDATED: { |
232 OnGoogleURLUpdated( | 277 OnGoogleURLUpdated( |
233 content::Source<Profile>(source).ptr(), | 278 content::Source<Profile>(source).ptr(), |
234 content::Details<GoogleURLTracker::UpdatedDetails>(details).ptr()); | 279 content::Details<GoogleURLTracker::UpdatedDetails>(details).ptr()); |
235 break; | 280 break; |
236 } | 281 } |
237 default: | 282 default: |
238 NOTREACHED() << "Unexpected notification type in InstantService."; | 283 NOTREACHED() << "Unexpected notification type in InstantService."; |
239 } | 284 } |
240 } | 285 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 // could cause that, neither of which we support. | 469 // could cause that, neither of which we support. |
425 return; | 470 return; |
426 } | 471 } |
427 | 472 |
428 ResetInstantSearchPrerenderer(); | 473 ResetInstantSearchPrerenderer(); |
429 | 474 |
430 FOR_EACH_OBSERVER( | 475 FOR_EACH_OBSERVER( |
431 InstantServiceObserver, observers_, DefaultSearchProviderChanged()); | 476 InstantServiceObserver, observers_, DefaultSearchProviderChanged()); |
432 } | 477 } |
433 | 478 |
| 479 InstantNTPPrerenderer* InstantService::ntp_prerenderer() { |
| 480 return &ntp_prerenderer_; |
| 481 } |
| 482 |
434 void InstantService::ResetInstantSearchPrerenderer() { | 483 void InstantService::ResetInstantSearchPrerenderer() { |
435 if (!chrome::ShouldPrefetchSearchResults()) | 484 if (!chrome::ShouldPrefetchSearchResults()) |
436 return; | 485 return; |
437 | 486 |
438 GURL url(chrome::GetSearchResultPrefetchBaseURL(profile_)); | 487 GURL url(chrome::GetSearchResultPrefetchBaseURL(profile_)); |
439 if (url.is_valid()) | 488 if (url.is_valid()) |
440 instant_prerenderer_.reset(new InstantSearchPrerenderer(profile_, url)); | 489 instant_prerenderer_.reset(new InstantSearchPrerenderer(profile_, url)); |
441 else | 490 else |
442 instant_prerenderer_.reset(); | 491 instant_prerenderer_.reset(); |
443 } | 492 } |
OLD | NEW |