Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / glue / webkit_glue.cc
blobd3b260f79299d747fc08db18e6862997256fdd2f
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
3 // found in the LICENSE file.
5 #include "webkit/glue/webkit_glue.h"
7 #if defined(OS_WIN)
8 #include <mlang.h>
9 #include <objidl.h>
10 #elif defined(OS_POSIX) && !defined(OS_MACOSX)
11 #include <sys/utsname.h>
12 #endif
14 #if defined(OS_LINUX)
15 #include <malloc.h>
16 #endif
18 #include <limits>
20 #include "base/logging.h"
21 #include "base/memory/scoped_ptr.h"
22 #include "base/path_service.h"
23 #include "base/process_util.h"
24 #include "base/string_piece.h"
25 #include "base/string_util.h"
26 #include "base/stringprintf.h"
27 #include "base/strings/string_tokenizer.h"
28 #include "base/sys_info.h"
29 #include "base/utf_string_conversions.h"
30 #include "net/base/escape.h"
31 #include "net/url_request/url_request.h"
32 #include "skia/ext/platform_canvas.h"
33 #if defined(OS_MACOSX)
34 #include "skia/ext/skia_utils_mac.h"
35 #endif
36 #include "third_party/WebKit/Source/Platform/chromium/public/WebData.h"
37 #include "third_party/WebKit/Source/Platform/chromium/public/WebFileInfo.h"
38 #include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h"
39 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
40 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
41 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
42 #include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebGlyphCache.h"
48 #include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
49 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
50 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPrintParams.h"
51 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
52 #if defined(OS_WIN)
53 #include "third_party/WebKit/Source/WebKit/chromium/public/win/WebInputEventFactory.h"
54 #endif
55 #include "third_party/skia/include/core/SkBitmap.h"
56 #include "v8/include/v8.h"
57 #include "webkit/glue/glue_serialize.h"
59 using WebKit::WebCanvas;
60 using WebKit::WebData;
61 using WebKit::WebDevToolsAgent;
62 using WebKit::WebElement;
63 using WebKit::WebFrame;
64 using WebKit::WebGlyphCache;
65 using WebKit::WebHistoryItem;
66 using WebKit::WebImage;
67 using WebKit::WebPrintParams;
68 using WebKit::WebRect;
69 using WebKit::WebSize;
70 using WebKit::WebString;
71 using WebKit::WebVector;
72 using WebKit::WebView;
74 static const char kLayoutTestsPattern[] = "/LayoutTests/";
75 static const std::string::size_type kLayoutTestsPatternSize =
76 arraysize(kLayoutTestsPattern) - 1;
77 static const char kFileUrlPattern[] = "file:/";
78 static const char kDataUrlPattern[] = "data:";
79 static const std::string::size_type kDataUrlPatternSize =
80 arraysize(kDataUrlPattern) - 1;
81 static const char kFileTestPrefix[] = "(file test):";
83 //------------------------------------------------------------------------------
84 // webkit_glue impl:
86 namespace webkit_glue {
88 // Global variable used by the plugin quirk "die after unload".
89 bool g_forcefully_terminate_plugin_process = false;
91 void SetJavaScriptFlags(const std::string& str) {
92 v8::V8::SetFlagsFromString(str.data(), static_cast<int>(str.size()));
95 void EnableWebCoreLogChannels(const std::string& channels) {
96 if (channels.empty())
97 return;
98 base::StringTokenizer t(channels, ", ");
99 while (t.GetNext()) {
100 WebKit::enableLogChannel(t.token().c_str());
104 base::string16 DumpDocumentText(WebFrame* web_frame) {
105 // We use the document element's text instead of the body text here because
106 // not all documents have a body, such as XML documents.
107 WebElement document_element = web_frame->document().documentElement();
108 if (document_element.isNull())
109 return base::string16();
111 return document_element.innerText();
114 base::string16 DumpFramesAsText(WebFrame* web_frame, bool recursive) {
115 base::string16 result;
117 // Add header for all but the main frame. Skip empty frames.
118 if (web_frame->parent() &&
119 !web_frame->document().documentElement().isNull()) {
120 result.append(ASCIIToUTF16("\n--------\nFrame: '"));
121 result.append(web_frame->uniqueName());
122 result.append(ASCIIToUTF16("'\n--------\n"));
125 result.append(DumpDocumentText(web_frame));
126 result.append(ASCIIToUTF16("\n"));
128 if (recursive) {
129 WebFrame* child = web_frame->firstChild();
130 for (; child; child = child->nextSibling())
131 result.append(DumpFramesAsText(child, recursive));
134 return result;
137 base::string16 DumpRenderer(WebFrame* web_frame) {
138 return web_frame->renderTreeAsText();
141 int NumberOfPages(WebFrame* web_frame,
142 float page_width_in_pixels,
143 float page_height_in_pixels) {
144 WebSize size(static_cast<int>(page_width_in_pixels),
145 static_cast<int>(page_height_in_pixels));
147 WebPrintParams print_params;
148 print_params.paperSize = size;
149 print_params.printContentArea = WebRect(0, 0, size.width, size.height);
150 print_params.printableArea = WebRect(0, 0, size.width, size.height);
152 int number_of_pages = web_frame->printBegin(print_params);
153 web_frame->printEnd();
154 return number_of_pages;
157 base::string16 DumpFrameScrollPosition(WebFrame* web_frame, bool recursive) {
158 gfx::Size offset = web_frame->scrollOffset();
159 std::string result_utf8;
161 if (offset.width() > 0 || offset.height() > 0) {
162 if (web_frame->parent()) {
163 base::StringAppendF(&result_utf8, "frame '%s' ",
164 UTF16ToUTF8(web_frame->uniqueName()).c_str());
166 base::StringAppendF(&result_utf8, "scrolled to %d,%d\n",
167 offset.width(), offset.height());
170 base::string16 result = UTF8ToUTF16(result_utf8);
172 if (recursive) {
173 WebFrame* child = web_frame->firstChild();
174 for (; child; child = child->nextSibling())
175 result.append(DumpFrameScrollPosition(child, recursive));
178 return result;
181 // Returns True if item1 < item2.
182 static bool HistoryItemCompareLess(const WebHistoryItem& item1,
183 const WebHistoryItem& item2) {
184 base::string16 target1 = item1.target();
185 base::string16 target2 = item2.target();
186 std::transform(target1.begin(), target1.end(), target1.begin(), tolower);
187 std::transform(target2.begin(), target2.end(), target2.begin(), tolower);
188 return target1 < target2;
191 // Writes out a HistoryItem into a UTF-8 string in a readable format.
192 static std::string DumpHistoryItem(const WebHistoryItem& item,
193 int indent, bool is_current) {
194 std::string result;
196 if (is_current) {
197 result.append("curr->");
198 result.append(indent - 6, ' '); // 6 == "curr->".length()
199 } else {
200 result.append(indent, ' ');
203 std::string url = item.urlString().utf8();
204 size_t pos;
205 if (url.find(kFileUrlPattern) == 0 &&
206 ((pos = url.find(kLayoutTestsPattern)) != std::string::npos)) {
207 // adjust file URLs to match upstream results.
208 url.replace(0, pos + kLayoutTestsPatternSize, kFileTestPrefix);
209 } else if (url.find(kDataUrlPattern) == 0) {
210 // URL-escape data URLs to match results upstream.
211 std::string path = net::EscapePath(url.substr(kDataUrlPatternSize));
212 url.replace(kDataUrlPatternSize, url.length(), path);
215 result.append(url);
216 if (!item.target().isEmpty())
217 result.append(" (in frame \"" + UTF16ToUTF8(item.target()) + "\")");
218 if (item.isTargetItem())
219 result.append(" **nav target**");
220 result.append("\n");
222 const WebVector<WebHistoryItem>& children = item.children();
223 if (!children.isEmpty()) {
224 // Must sort to eliminate arbitrary result ordering which defeats
225 // reproducible testing.
226 // TODO(darin): WebVector should probably just be a std::vector!!
227 std::vector<WebHistoryItem> sorted_children;
228 for (size_t i = 0; i < children.size(); ++i)
229 sorted_children.push_back(children[i]);
230 std::sort(sorted_children.begin(), sorted_children.end(),
231 HistoryItemCompareLess);
232 for (size_t i = 0; i < sorted_children.size(); i++)
233 result += DumpHistoryItem(sorted_children[i], indent+4, false);
236 return result;
239 base::string16 DumpHistoryState(const std::string& history_state, int indent,
240 bool is_current) {
241 return UTF8ToUTF16(
242 DumpHistoryItem(HistoryItemFromString(history_state), indent,
243 is_current));
246 #ifndef NDEBUG
247 // The log macro was having problems due to collisions with WTF, so we just
248 // code here what that would have inlined.
249 void DumpLeakedObject(const char* file, int line, const char* object,
250 int count) {
251 std::string msg = base::StringPrintf("%s LEAKED %d TIMES", object, count);
252 logging::LogMessage(file, line).stream() << msg;
254 #endif
256 void CheckForLeaks() {
257 #ifndef NDEBUG
258 int count = WebFrame::instanceCount();
259 if (count)
260 DumpLeakedObject(__FILE__, __LINE__, "WebFrame", count);
261 #endif
264 bool DecodeImage(const std::string& image_data, SkBitmap* image) {
265 WebData web_data(image_data.data(), image_data.length());
266 WebImage web_image(WebImage::fromData(web_data, WebSize()));
267 if (web_image.isNull())
268 return false;
270 *image = web_image.getSkBitmap();
271 return true;
274 void PlatformFileInfoToWebFileInfo(
275 const base::PlatformFileInfo& file_info,
276 WebKit::WebFileInfo* web_file_info) {
277 DCHECK(web_file_info);
278 // WebKit now expects NaN as uninitialized/null Date.
279 if (file_info.last_modified.is_null())
280 web_file_info->modificationTime = std::numeric_limits<double>::quiet_NaN();
281 else
282 web_file_info->modificationTime = file_info.last_modified.ToDoubleT();
283 web_file_info->length = file_info.size;
284 if (file_info.is_directory)
285 web_file_info->type = WebKit::WebFileInfo::TypeDirectory;
286 else
287 web_file_info->type = WebKit::WebFileInfo::TypeFile;
290 void SetForcefullyTerminatePluginProcess(bool value) {
291 g_forcefully_terminate_plugin_process = value;
294 bool ShouldForcefullyTerminatePluginProcess() {
295 return g_forcefully_terminate_plugin_process;
298 WebCanvas* ToWebCanvas(skia::PlatformCanvas* canvas) {
299 return canvas;
302 int GetGlyphPageCount() {
303 return WebGlyphCache::pageCount();
306 std::string GetInspectorProtocolVersion() {
307 return WebDevToolsAgent::inspectorProtocolVersion().utf8();
310 bool IsInspectorProtocolVersionSupported(const std::string& version) {
311 return WebDevToolsAgent::supportsInspectorProtocolVersion(
312 WebString::fromUTF8(version));
315 void ConfigureURLRequestForReferrerPolicy(
316 net::URLRequest* request, WebKit::WebReferrerPolicy referrer_policy) {
317 net::URLRequest::ReferrerPolicy net_referrer_policy =
318 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
319 switch (referrer_policy) {
320 case WebKit::WebReferrerPolicyDefault:
321 net_referrer_policy =
322 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
323 break;
325 case WebKit::WebReferrerPolicyAlways:
326 case WebKit::WebReferrerPolicyNever:
327 case WebKit::WebReferrerPolicyOrigin:
328 net_referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER;
329 break;
331 request->set_referrer_policy(net_referrer_policy);
334 COMPILE_ASSERT(std::numeric_limits<double>::has_quiet_NaN, has_quiet_NaN);
336 #if defined(OS_LINUX) || defined(OS_ANDROID)
337 size_t MemoryUsageKB() {
338 struct mallinfo minfo = mallinfo();
339 uint64_t mem_usage =
340 #if defined(USE_TCMALLOC)
341 minfo.uordblks
342 #else
343 (minfo.hblkhd + minfo.arena)
344 #endif
345 >> 10;
347 v8::HeapStatistics stat;
348 // TODO(svenpanne) The call below doesn't take web workers into account, this
349 // has to be done manually by iterating over all Isolates involved.
350 v8::Isolate::GetCurrent()->GetHeapStatistics(&stat);
351 return mem_usage + (static_cast<uint64_t>(stat.total_heap_size()) >> 10);
353 #elif defined(OS_MACOSX)
354 size_t MemoryUsageKB() {
355 scoped_ptr<base::ProcessMetrics> process_metrics(
356 // The default port provider is sufficient to get data for the current
357 // process.
358 base::ProcessMetrics::CreateProcessMetrics(
359 base::GetCurrentProcessHandle(), NULL));
360 return process_metrics->GetWorkingSetSize() >> 10;
362 #else
363 size_t MemoryUsageKB() {
364 scoped_ptr<base::ProcessMetrics> process_metrics(
365 base::ProcessMetrics::CreateProcessMetrics(
366 base::GetCurrentProcessHandle()));
367 return process_metrics->GetPagefileUsage() >> 10;
369 #endif
371 double ZoomFactorToZoomLevel(double factor) {
372 return WebView::zoomFactorToZoomLevel(factor);
375 } // namespace webkit_glue