OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/thumbnails/thumbnail_tab_helper.h" | 5 #include "chrome/browser/thumbnails/thumbnail_tab_helper.h" |
6 | 6 |
7 #include "chrome/browser/browser_process.h" | 7 #include "chrome/browser/browser_process.h" |
8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
9 #include "chrome/browser/thumbnails/thumbnail_service.h" | 9 #include "chrome/browser/thumbnails/thumbnail_service.h" |
10 #include "chrome/browser/thumbnails/thumbnail_service_factory.h" | 10 #include "chrome/browser/thumbnails/thumbnail_service_factory.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 using thumbnails::ClipResult; | 51 using thumbnails::ClipResult; |
52 using thumbnails::ThumbnailingContext; | 52 using thumbnails::ThumbnailingContext; |
53 using thumbnails::ThumbnailingAlgorithm; | 53 using thumbnails::ThumbnailingAlgorithm; |
54 | 54 |
55 namespace { | 55 namespace { |
56 | 56 |
57 // Feed the constructed thumbnail to the thumbnail service. | 57 // Feed the constructed thumbnail to the thumbnail service. |
58 void UpdateThumbnail(const ThumbnailingContext& context, | 58 void UpdateThumbnail(const ThumbnailingContext& context, |
59 const SkBitmap& thumbnail) { | 59 const SkBitmap& thumbnail) { |
60 gfx::Image image = gfx::Image::CreateFrom1xBitmap(thumbnail); | 60 gfx::Image image = gfx::Image::CreateFrom1xBitmap(thumbnail); |
61 context.service()->SetPageThumbnail(context, image); | 61 context.service->SetPageThumbnail(context, image); |
62 DVLOG(1) << "Thumbnail taken for " << context.GetURL() << ": " | 62 DVLOG(1) << "Thumbnail taken for " << context.url << ": " |
63 << context.score().ToString(); | 63 << context.score.ToString(); |
64 } | 64 } |
65 | 65 |
66 void ProcessCapturedBitmap(scoped_refptr<ThumbnailingContext> context, | 66 void ProcessCapturedBitmap(scoped_refptr<ThumbnailingContext> context, |
67 scoped_refptr<ThumbnailingAlgorithm> algorithm, | 67 scoped_refptr<ThumbnailingAlgorithm> algorithm, |
68 const SkBitmap& bitmap, | 68 const SkBitmap& bitmap, |
69 content::ReadbackResponse response) { | 69 content::ReadbackResponse response) { |
70 // Was the web contents destroyed before the thumbnail could be generated? | |
71 if (!context->web_contents()) | |
72 return; | |
73 | |
74 // Balance the IncrementCapturerCount() from UpdateThumbnailIfNecessary(). | |
75 context->web_contents()->DecrementCapturerCount(); | |
76 | |
77 if (response != content::READBACK_SUCCESS) | 70 if (response != content::READBACK_SUCCESS) |
78 return; | 71 return; |
79 | 72 |
80 // On success, we must be on the UI thread (on failure because of shutdown we | 73 // On success, we must be on the UI thread (on failure because of shutdown we |
81 // are not on the UI thread). | 74 // are not on the UI thread). |
82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 75 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
83 | 76 |
84 algorithm->ProcessBitmap(context, base::Bind(&UpdateThumbnail), bitmap); | 77 algorithm->ProcessBitmap(context, base::Bind(&UpdateThumbnail), bitmap); |
85 } | 78 } |
86 | 79 |
87 void AsyncProcessThumbnail(scoped_refptr<ThumbnailingContext> context, | 80 void AsyncProcessThumbnail(content::WebContents* web_contents, |
| 81 scoped_refptr<ThumbnailingContext> context, |
88 scoped_refptr<ThumbnailingAlgorithm> algorithm) { | 82 scoped_refptr<ThumbnailingAlgorithm> algorithm) { |
89 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 83 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
90 RenderWidgetHost* render_widget_host = | 84 RenderWidgetHost* render_widget_host = |
91 context->web_contents()->GetRenderViewHost()->GetWidget(); | 85 web_contents->GetRenderViewHost()->GetWidget(); |
92 content::RenderWidgetHostView* view = render_widget_host->GetView(); | 86 content::RenderWidgetHostView* view = render_widget_host->GetView(); |
93 if (!view) | 87 if (!view) |
94 return; | 88 return; |
95 if (!view->IsSurfaceAvailableForCopy()) | 89 if (!view->IsSurfaceAvailableForCopy()) |
96 return; | 90 return; |
97 | 91 |
98 gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size()); | 92 gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size()); |
99 // Clip the pixels that will commonly hold a scrollbar, which looks bad in | 93 // Clip the pixels that will commonly hold a scrollbar, which looks bad in |
100 // thumbnails. | 94 // thumbnails. |
101 int scrollbar_size = gfx::scrollbar_size(); | 95 int scrollbar_size = gfx::scrollbar_size(); |
102 gfx::Size copy_size; | 96 gfx::Size copy_size; |
103 copy_rect.Inset(0, 0, scrollbar_size, scrollbar_size); | 97 copy_rect.Inset(0, 0, scrollbar_size, scrollbar_size); |
104 | 98 |
105 if (copy_rect.IsEmpty()) | 99 if (copy_rect.IsEmpty()) |
106 return; | 100 return; |
107 | 101 |
108 ui::ScaleFactor scale_factor = | 102 ui::ScaleFactor scale_factor = |
109 ui::GetSupportedScaleFactor( | 103 ui::GetSupportedScaleFactor( |
110 ui::GetScaleFactorForNativeView(view->GetNativeView())); | 104 ui::GetScaleFactorForNativeView(view->GetNativeView())); |
111 gfx::Size requested_copy_size; | 105 context->clip_result = algorithm->GetCanvasCopyInfo( |
112 context->set_clip_result(algorithm->GetCanvasCopyInfo( | |
113 copy_rect.size(), | 106 copy_rect.size(), |
114 scale_factor, | 107 scale_factor, |
115 ©_rect, | 108 ©_rect, |
116 &requested_copy_size)); | 109 &context->requested_copy_size); |
117 context->set_requested_copy_size(requested_copy_size); | |
118 render_widget_host->CopyFromBackingStore( | 110 render_widget_host->CopyFromBackingStore( |
119 copy_rect, | 111 copy_rect, |
120 requested_copy_size, | 112 context->requested_copy_size, |
121 base::Bind(&ProcessCapturedBitmap, context, algorithm), | 113 base::Bind(&ProcessCapturedBitmap, context, algorithm), |
122 kN32_SkColorType); | 114 kN32_SkColorType); |
123 } | 115 } |
124 | 116 |
125 } // namespace | 117 } // namespace |
126 | 118 |
127 ThumbnailTabHelper::ThumbnailTabHelper(content::WebContents* contents) | 119 ThumbnailTabHelper::ThumbnailTabHelper(content::WebContents* contents) |
128 : content::WebContentsObserver(contents), | 120 : content::WebContentsObserver(contents), |
129 load_interrupted_(false) { | 121 load_interrupted_(false) { |
130 // Even though we deal in RenderWidgetHosts, we only care about its | 122 // Even though we deal in RenderWidgetHosts, we only care about its |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 | 188 |
197 scoped_refptr<thumbnails::ThumbnailService> thumbnail_service = | 189 scoped_refptr<thumbnails::ThumbnailService> thumbnail_service = |
198 ThumbnailServiceFactory::GetForProfile(profile); | 190 ThumbnailServiceFactory::GetForProfile(profile); |
199 | 191 |
200 // Skip if we don't need to update the thumbnail. | 192 // Skip if we don't need to update the thumbnail. |
201 if (thumbnail_service.get() == NULL || | 193 if (thumbnail_service.get() == NULL || |
202 !thumbnail_service->ShouldAcquirePageThumbnail(url)) { | 194 !thumbnail_service->ShouldAcquirePageThumbnail(url)) { |
203 return; | 195 return; |
204 } | 196 } |
205 | 197 |
206 web_contents->IncrementCapturerCount(gfx::Size()); | |
207 | |
208 scoped_refptr<thumbnails::ThumbnailingAlgorithm> algorithm( | 198 scoped_refptr<thumbnails::ThumbnailingAlgorithm> algorithm( |
209 thumbnail_service->GetThumbnailingAlgorithm()); | 199 thumbnail_service->GetThumbnailingAlgorithm()); |
210 | 200 |
211 scoped_refptr<ThumbnailingContext> context(new ThumbnailingContext( | 201 scoped_refptr<ThumbnailingContext> context(new ThumbnailingContext( |
212 web_contents, thumbnail_service.get(), load_interrupted_)); | 202 web_contents, thumbnail_service.get(), load_interrupted_)); |
213 AsyncProcessThumbnail(context, algorithm); | 203 AsyncProcessThumbnail(web_contents, context, algorithm); |
214 } | 204 } |
215 | 205 |
216 void ThumbnailTabHelper::RenderViewHostCreated( | 206 void ThumbnailTabHelper::RenderViewHostCreated( |
217 content::RenderViewHost* renderer) { | 207 content::RenderViewHost* renderer) { |
218 // NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED is really a new | 208 // NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED is really a new |
219 // RenderView, not RenderViewHost, and there is no good way to get | 209 // RenderView, not RenderViewHost, and there is no good way to get |
220 // notifications of RenderViewHosts. So just be tolerant of re-registrations. | 210 // notifications of RenderViewHosts. So just be tolerant of re-registrations. |
221 bool registered = registrar_.IsRegistered( | 211 bool registered = registrar_.IsRegistered( |
222 this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | 212 this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
223 content::Source<RenderWidgetHost>(renderer->GetWidget())); | 213 content::Source<RenderWidgetHost>(renderer->GetWidget())); |
224 if (!registered) { | 214 if (!registered) { |
225 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | 215 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
226 content::Source<RenderWidgetHost>(renderer->GetWidget())); | 216 content::Source<RenderWidgetHost>(renderer->GetWidget())); |
227 } | 217 } |
228 } | 218 } |
229 | 219 |
230 void ThumbnailTabHelper::WidgetHidden(RenderWidgetHost* widget) { | 220 void ThumbnailTabHelper::WidgetHidden(RenderWidgetHost* widget) { |
231 UpdateThumbnailIfNecessary(web_contents()); | 221 UpdateThumbnailIfNecessary(web_contents()); |
232 } | 222 } |
OLD | NEW |