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/renderer/chrome_render_view_observer.h" | 5 #include "chrome/renderer/chrome_render_view_observer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/strings/string_split.h" |
13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
14 #include "chrome/common/chrome_constants.h" | 15 #include "chrome/common/chrome_constants.h" |
15 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
16 #include "chrome/common/prerender_messages.h" | 17 #include "chrome/common/prerender_messages.h" |
17 #include "chrome/common/render_messages.h" | 18 #include "chrome/common/render_messages.h" |
18 #include "chrome/common/url_constants.h" | 19 #include "chrome/common/url_constants.h" |
19 #include "chrome/renderer/chrome_render_process_observer.h" | 20 #include "chrome/renderer/chrome_render_process_observer.h" |
20 #include "chrome/renderer/content_settings_observer.h" | 21 #include "chrome/renderer/content_settings_observer.h" |
21 #include "chrome/renderer/extensions/dispatcher.h" | 22 #include "chrome/renderer/extensions/dispatcher.h" |
22 #include "chrome/renderer/external_host_bindings.h" | 23 #include "chrome/renderer/external_host_bindings.h" |
23 #include "chrome/renderer/frame_sniffer.h" | 24 #include "chrome/renderer/frame_sniffer.h" |
24 #include "chrome/renderer/prerender/prerender_helper.h" | 25 #include "chrome/renderer/prerender/prerender_helper.h" |
25 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" | 26 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" |
26 #include "chrome/renderer/translate/translate_helper.h" | 27 #include "chrome/renderer/translate/translate_helper.h" |
27 #include "chrome/renderer/webview_color_overlay.h" | 28 #include "chrome/renderer/webview_color_overlay.h" |
28 #include "content/public/common/bindings_policy.h" | 29 #include "content/public/common/bindings_policy.h" |
29 #include "content/public/renderer/content_renderer_client.h" | 30 #include "content/public/renderer/content_renderer_client.h" |
30 #include "content/public/renderer/render_view.h" | 31 #include "content/public/renderer/render_view.h" |
31 #include "extensions/common/constants.h" | 32 #include "extensions/common/constants.h" |
| 33 #include "extensions/common/stack_frame.h" |
32 #include "net/base/data_url.h" | 34 #include "net/base/data_url.h" |
33 #include "skia/ext/image_operations.h" | 35 #include "skia/ext/image_operations.h" |
34 #include "skia/ext/platform_canvas.h" | 36 #include "skia/ext/platform_canvas.h" |
35 #include "third_party/WebKit/public/platform/WebCString.h" | 37 #include "third_party/WebKit/public/platform/WebCString.h" |
36 #include "third_party/WebKit/public/platform/WebRect.h" | 38 #include "third_party/WebKit/public/platform/WebRect.h" |
37 #include "third_party/WebKit/public/platform/WebSize.h" | 39 #include "third_party/WebKit/public/platform/WebSize.h" |
38 #include "third_party/WebKit/public/platform/WebString.h" | 40 #include "third_party/WebKit/public/platform/WebString.h" |
39 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 41 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
40 #include "third_party/WebKit/public/platform/WebVector.h" | 42 #include "third_party/WebKit/public/platform/WebVector.h" |
41 #include "third_party/WebKit/public/web/WebAccessibilityObject.h" | 43 #include "third_party/WebKit/public/web/WebAccessibilityObject.h" |
42 #include "third_party/WebKit/public/web/WebDataSource.h" | 44 #include "third_party/WebKit/public/web/WebDataSource.h" |
43 #include "third_party/WebKit/public/web/WebDocument.h" | 45 #include "third_party/WebKit/public/web/WebDocument.h" |
44 #include "third_party/WebKit/public/web/WebElement.h" | 46 #include "third_party/WebKit/public/web/WebElement.h" |
45 #include "third_party/WebKit/public/web/WebFrame.h" | 47 #include "third_party/WebKit/public/web/WebFrame.h" |
46 #include "third_party/WebKit/public/web/WebInputEvent.h" | 48 #include "third_party/WebKit/public/web/WebInputEvent.h" |
47 #include "third_party/WebKit/public/web/WebNode.h" | 49 #include "third_party/WebKit/public/web/WebNode.h" |
48 #include "third_party/WebKit/public/web/WebNodeList.h" | 50 #include "third_party/WebKit/public/web/WebNodeList.h" |
49 #include "third_party/WebKit/public/web/WebView.h" | 51 #include "third_party/WebKit/public/web/WebView.h" |
50 #include "ui/base/ui_base_switches_util.h" | 52 #include "ui/base/ui_base_switches_util.h" |
51 #include "ui/gfx/favicon_size.h" | 53 #include "ui/gfx/favicon_size.h" |
52 #include "ui/gfx/size.h" | 54 #include "ui/gfx/size.h" |
53 #include "ui/gfx/size_f.h" | 55 #include "ui/gfx/size_f.h" |
54 #include "ui/gfx/skbitmap_operations.h" | 56 #include "ui/gfx/skbitmap_operations.h" |
55 #include "v8/include/v8-testing.h" | 57 #include "v8/include/v8-testing.h" |
56 #include "webkit/glue/webkit_glue.h" | 58 #include "webkit/glue/webkit_glue.h" |
57 | 59 |
| 60 using base::string16; |
| 61 using extensions::APIPermission; |
58 using WebKit::WebAccessibilityObject; | 62 using WebKit::WebAccessibilityObject; |
59 using WebKit::WebCString; | 63 using WebKit::WebCString; |
60 using WebKit::WebDataSource; | 64 using WebKit::WebDataSource; |
61 using WebKit::WebDocument; | 65 using WebKit::WebDocument; |
62 using WebKit::WebElement; | 66 using WebKit::WebElement; |
63 using WebKit::WebFrame; | 67 using WebKit::WebFrame; |
64 using WebKit::WebGestureEvent; | 68 using WebKit::WebGestureEvent; |
65 using WebKit::WebIconURL; | 69 using WebKit::WebIconURL; |
66 using WebKit::WebNode; | 70 using WebKit::WebNode; |
67 using WebKit::WebNodeList; | 71 using WebKit::WebNodeList; |
68 using WebKit::WebRect; | 72 using WebKit::WebRect; |
69 using WebKit::WebSecurityOrigin; | 73 using WebKit::WebSecurityOrigin; |
70 using WebKit::WebSize; | 74 using WebKit::WebSize; |
71 using WebKit::WebString; | 75 using WebKit::WebString; |
72 using WebKit::WebTouchEvent; | 76 using WebKit::WebTouchEvent; |
73 using WebKit::WebURL; | 77 using WebKit::WebURL; |
74 using WebKit::WebURLRequest; | 78 using WebKit::WebURLRequest; |
75 using WebKit::WebView; | 79 using WebKit::WebView; |
76 using WebKit::WebVector; | 80 using WebKit::WebVector; |
77 using WebKit::WebWindowFeatures; | 81 using WebKit::WebWindowFeatures; |
78 using extensions::APIPermission; | |
79 | 82 |
80 // Delay in milliseconds that we'll wait before capturing the page contents | 83 // Delay in milliseconds that we'll wait before capturing the page contents |
81 // and thumbnail. | 84 // and thumbnail. |
82 static const int kDelayForCaptureMs = 500; | 85 static const int kDelayForCaptureMs = 500; |
83 | 86 |
84 // Typically, we capture the page data once the page is loaded. | 87 // Typically, we capture the page data once the page is loaded. |
85 // Sometimes, the page never finishes to load, preventing the page capture | 88 // Sometimes, the page never finishes to load, preventing the page capture |
86 // To workaround this problem, we always perform a capture after the following | 89 // To workaround this problem, we always perform a capture after the following |
87 // delay. | 90 // delay. |
88 static const int kDelayForForcedCaptureMs = 6000; | 91 static const int kDelayForForcedCaptureMs = 6000; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 static const char kGoogleDotCom[] = "google.com"; | 162 static const char kGoogleDotCom[] = "google.com"; |
160 | 163 |
161 static bool isHostInDomain(const std::string& host, const std::string& domain) { | 164 static bool isHostInDomain(const std::string& host, const std::string& domain) { |
162 return (EndsWith(host, domain, false) && | 165 return (EndsWith(host, domain, false) && |
163 (host.length() == domain.length() || | 166 (host.length() == domain.length() || |
164 (host.length() > domain.length() && | 167 (host.length() > domain.length() && |
165 host[host.length() - domain.length() - 1] == '.'))); | 168 host[host.length() - domain.length() - 1] == '.'))); |
166 } | 169 } |
167 | 170 |
168 namespace { | 171 namespace { |
| 172 |
169 GURL StripRef(const GURL& url) { | 173 GURL StripRef(const GURL& url) { |
170 GURL::Replacements replacements; | 174 GURL::Replacements replacements; |
171 replacements.ClearRef(); | 175 replacements.ClearRef(); |
172 return url.ReplaceComponents(replacements); | 176 return url.ReplaceComponents(replacements); |
173 } | 177 } |
174 | 178 |
175 // If the source image is null or occupies less area than | 179 // If the source image is null or occupies less area than |
176 // |thumbnail_min_area_pixels|, we return the image unmodified. Otherwise, we | 180 // |thumbnail_min_area_pixels|, we return the image unmodified. Otherwise, we |
177 // scale down the image so that the width and height do not exceed | 181 // scale down the image so that the width and height do not exceed |
178 // |thumbnail_max_size_pixels|, preserving the original aspect ratio. | 182 // |thumbnail_max_size_pixels|, preserving the original aspect ratio. |
179 static SkBitmap Downscale(WebKit::WebImage image, | 183 SkBitmap Downscale(WebKit::WebImage image, |
180 int thumbnail_min_area_pixels, | 184 int thumbnail_min_area_pixels, |
181 gfx::Size thumbnail_max_size_pixels) { | 185 gfx::Size thumbnail_max_size_pixels) { |
182 if (image.isNull()) | 186 if (image.isNull()) |
183 return SkBitmap(); | 187 return SkBitmap(); |
184 | 188 |
185 gfx::Size image_size = image.size(); | 189 gfx::Size image_size = image.size(); |
186 | 190 |
187 if (image_size.GetArea() < thumbnail_min_area_pixels) | 191 if (image_size.GetArea() < thumbnail_min_area_pixels) |
188 return image.getSkBitmap(); | 192 return image.getSkBitmap(); |
189 | 193 |
190 if (image_size.width() <= thumbnail_max_size_pixels.width() && | 194 if (image_size.width() <= thumbnail_max_size_pixels.width() && |
191 image_size.height() <= thumbnail_max_size_pixels.height()) | 195 image_size.height() <= thumbnail_max_size_pixels.height()) |
192 return image.getSkBitmap(); | 196 return image.getSkBitmap(); |
193 | 197 |
194 gfx::SizeF scaled_size = image_size; | 198 gfx::SizeF scaled_size = image_size; |
195 | 199 |
196 if (scaled_size.width() > thumbnail_max_size_pixels.width()) { | 200 if (scaled_size.width() > thumbnail_max_size_pixels.width()) { |
197 scaled_size.Scale(thumbnail_max_size_pixels.width() / scaled_size.width()); | 201 scaled_size.Scale(thumbnail_max_size_pixels.width() / scaled_size.width()); |
198 } | 202 } |
199 | 203 |
200 if (scaled_size.height() > thumbnail_max_size_pixels.height()) { | 204 if (scaled_size.height() > thumbnail_max_size_pixels.height()) { |
201 scaled_size.Scale( | 205 scaled_size.Scale( |
202 thumbnail_max_size_pixels.height() / scaled_size.height()); | 206 thumbnail_max_size_pixels.height() / scaled_size.height()); |
203 } | 207 } |
204 | 208 |
205 return skia::ImageOperations::Resize(image.getSkBitmap(), | 209 return skia::ImageOperations::Resize(image.getSkBitmap(), |
206 skia::ImageOperations::RESIZE_GOOD, | 210 skia::ImageOperations::RESIZE_GOOD, |
207 static_cast<int>(scaled_size.width()), | 211 static_cast<int>(scaled_size.width()), |
208 static_cast<int>(scaled_size.height())); | 212 static_cast<int>(scaled_size.height())); |
209 } | 213 } |
| 214 |
| 215 // The delimiter for a stack trace provided by WebKit. |
| 216 const char kStackFrameDelimiter[] = "\n at "; |
| 217 |
| 218 // Get a stack trace from a WebKit console message. |
| 219 // There are three possible scenarios: |
| 220 // 1. WebKit gives us a stack trace in |stack_trace|. |
| 221 // 2. The stack trace is embedded in the error |message| by an internal |
| 222 // script. This will be more useful than |stack_trace|, since |stack_trace| |
| 223 // will include the internal bindings trace, instead of a developer's code. |
| 224 // 3. No stack trace is included. In this case, we should mock one up from |
| 225 // the given line number and source. |
| 226 // |message| will be populated with the error message only (i.e., will not |
| 227 // include any stack trace). |
| 228 extensions::StackTrace GetStackTraceFromMessage(string16* message, |
| 229 const string16& source, |
| 230 const string16& stack_trace, |
| 231 int32 line_number) { |
| 232 extensions::StackTrace result; |
| 233 std::vector<base::string16> pieces; |
| 234 size_t index = 0; |
| 235 |
| 236 if (message->find(base::UTF8ToUTF16(kStackFrameDelimiter)) != |
| 237 string16::npos) { |
| 238 base::SplitStringUsingSubstr(*message, |
| 239 base::UTF8ToUTF16(kStackFrameDelimiter), |
| 240 &pieces); |
| 241 *message = pieces[0]; |
| 242 index = 1; |
| 243 } else if (!stack_trace.empty()) { |
| 244 base::SplitStringUsingSubstr(stack_trace, |
| 245 base::UTF8ToUTF16(kStackFrameDelimiter), |
| 246 &pieces); |
| 247 } |
| 248 |
| 249 // If we got a stack trace, parse each frame from the text. |
| 250 if (index < pieces.size()) { |
| 251 for (; index < pieces.size(); ++index) { |
| 252 scoped_ptr<extensions::StackFrame> frame = |
| 253 extensions::StackFrame::CreateFromText(pieces[index]); |
| 254 if (frame.get()) |
| 255 result.push_back(*frame); |
| 256 } |
| 257 } |
| 258 |
| 259 if (result.empty()) { // If we don't have a stack trace, mock one up. |
| 260 result.push_back( |
| 261 extensions::StackFrame(line_number, |
| 262 1u, // column number |
| 263 source, |
| 264 EmptyString16() /* no function name */ )); |
| 265 } |
| 266 |
| 267 return result; |
| 268 } |
| 269 |
210 } // namespace | 270 } // namespace |
211 | 271 |
212 ChromeRenderViewObserver::ChromeRenderViewObserver( | 272 ChromeRenderViewObserver::ChromeRenderViewObserver( |
213 content::RenderView* render_view, | 273 content::RenderView* render_view, |
214 ContentSettingsObserver* content_settings, | 274 ContentSettingsObserver* content_settings, |
215 ChromeRenderProcessObserver* chrome_render_process_observer, | 275 ChromeRenderProcessObserver* chrome_render_process_observer, |
216 extensions::Dispatcher* extension_dispatcher) | 276 extensions::Dispatcher* extension_dispatcher) |
217 : content::RenderViewObserver(render_view), | 277 : content::RenderViewObserver(render_view), |
218 chrome_render_process_observer_(chrome_render_process_observer), | 278 chrome_render_process_observer_(chrome_render_process_observer), |
219 extension_dispatcher_(extension_dispatcher), | 279 extension_dispatcher_(extension_dispatcher), |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 return; | 820 return; |
761 | 821 |
762 WebKit::WebTextInputType text_input_type = | 822 WebKit::WebTextInputType text_input_type = |
763 render_view()->GetWebView()->textInputInfo().type; | 823 render_view()->GetWebView()->textInputInfo().type; |
764 | 824 |
765 render_view()->Send(new ChromeViewHostMsg_FocusedNodeTouched( | 825 render_view()->Send(new ChromeViewHostMsg_FocusedNodeTouched( |
766 routing_id(), | 826 routing_id(), |
767 text_input_type != WebKit::WebTextInputTypeNone)); | 827 text_input_type != WebKit::WebTextInputTypeNone)); |
768 } | 828 } |
769 | 829 |
| 830 void ChromeRenderViewObserver::OnDetailedConsoleMessageAdded( |
| 831 const base::string16& message, |
| 832 const base::string16& source, |
| 833 const base::string16& stack_trace_string, |
| 834 int32 line_number, |
| 835 int32 severity_level) { |
| 836 string16 trimmed_message = message; |
| 837 extensions::StackTrace stack_trace = GetStackTraceFromMessage( |
| 838 &trimmed_message, |
| 839 source, |
| 840 stack_trace_string, |
| 841 line_number); |
| 842 Send(new ChromeViewHostMsg_DetailedConsoleMessageAdded(routing_id(), |
| 843 trimmed_message, |
| 844 source, |
| 845 stack_trace, |
| 846 severity_level)); |
| 847 } |
| 848 |
770 void ChromeRenderViewObserver::CapturePageInfoLater(int page_id, | 849 void ChromeRenderViewObserver::CapturePageInfoLater(int page_id, |
771 bool preliminary_capture, | 850 bool preliminary_capture, |
772 base::TimeDelta delay) { | 851 base::TimeDelta delay) { |
773 capture_timer_.Start( | 852 capture_timer_.Start( |
774 FROM_HERE, | 853 FROM_HERE, |
775 delay, | 854 delay, |
776 base::Bind(&ChromeRenderViewObserver::CapturePageInfo, | 855 base::Bind(&ChromeRenderViewObserver::CapturePageInfo, |
777 base::Unretained(this), | 856 base::Unretained(this), |
778 page_id, | 857 page_id, |
779 preliminary_capture)); | 858 preliminary_capture)); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 WebElement element = node.to<WebElement>(); | 1009 WebElement element = node.to<WebElement>(); |
931 if (!element.hasTagName(tag_name)) | 1010 if (!element.hasTagName(tag_name)) |
932 continue; | 1011 continue; |
933 WebString value = element.getAttribute(attribute_name); | 1012 WebString value = element.getAttribute(attribute_name); |
934 if (value.isNull() || !LowerCaseEqualsASCII(value, "refresh")) | 1013 if (value.isNull() || !LowerCaseEqualsASCII(value, "refresh")) |
935 continue; | 1014 continue; |
936 return true; | 1015 return true; |
937 } | 1016 } |
938 return false; | 1017 return false; |
939 } | 1018 } |
OLD | NEW |