summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/renderer_glue.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer/renderer_glue.cc')
-rw-r--r--chrome/renderer/renderer_glue.cc407
1 files changed, 407 insertions, 0 deletions
diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc
new file mode 100644
index 0000000..cfe1d9c
--- /dev/null
+++ b/chrome/renderer/renderer_glue.cc
@@ -0,0 +1,407 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file provides the embedder's side of random webkit glue functions.
+
+#include <windows.h>
+#include <wininet.h>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "chrome/renderer/net/render_dns_master.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/common/resource_dispatcher.h"
+#include "chrome/plugin/npobject_util.h"
+#include "chrome/renderer/render_process.h"
+#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/render_view.h"
+#include "chrome/renderer/visitedlink_slave.h"
+#include "googleurl/src/gurl.h"
+#include "googleurl/src/url_util.h"
+#include "net/base/mime_util.h"
+#include "webkit/glue/resource_type.h"
+#include "webkit/glue/webframe.h"
+#include "webkit/glue/webview.h"
+#include "webkit/glue/webkit_glue.h"
+
+#include "SkBitmap.h"
+
+#include <strsafe.h> // note: per msdn docs, this must *follow* other includes
+
+template <typename T, size_t stack_capacity>
+class ResizableStackArray {
+ public:
+ ResizableStackArray()
+ : cur_buffer_(stack_buffer_), cur_capacity_(stack_capacity) {
+ }
+ ~ResizableStackArray() {
+ FreeHeap();
+ }
+
+ T* get() const {
+ return cur_buffer_;
+ }
+
+ T& operator[](size_t i) {
+ return cur_buffer_[i];
+ }
+
+ size_t capacity() const {
+ return cur_capacity_;
+ }
+
+ void Resize(size_t new_size) {
+ if (new_size < cur_capacity_)
+ return; // already big enough
+ FreeHeap();
+ cur_capacity_ = new_size;
+ cur_buffer_ = new T[new_size];
+ }
+
+ private:
+ // Resets the heap buffer, if any
+ void FreeHeap() {
+ if (cur_buffer_ != stack_buffer_) {
+ delete[] cur_buffer_;
+ cur_buffer_ = stack_buffer_;
+ cur_capacity_ = stack_capacity;
+ }
+ }
+
+ T stack_buffer_[stack_capacity];
+ T* cur_buffer_;
+ size_t cur_capacity_;
+};
+
+namespace webkit_glue {
+
+bool HistoryContains(const wchar_t* url, int url_length,
+ const char* document_host, int document_host_length,
+ bool is_dns_prefetch_enabled) {
+ if (url_length == 0)
+ return false; // Empty URLs are not visited.
+
+ // Use big stack buffer to avoid allocation when possible.
+ url_parse::Parsed parsed;
+ url_canon::RawCanonOutput<2048> canon;
+
+ if (!url_util::Canonicalize(url, url_length, NULL, &canon, &parsed))
+ return false; // Invalid URLs are not visited.
+
+ char* parsed_host = canon.data() + parsed.host.begin;
+
+ // If the hostnames match or is_dns_prefetch_enabled is true, do the prefetch.
+ if (parsed.host.is_nonempty()) {
+ if (is_dns_prefetch_enabled ||
+ (document_host_length > 0 && parsed.host.len == document_host_length &&
+ strncmp(parsed_host, document_host, parsed.host.len) == 0))
+ DnsPrefetchCString(parsed_host, parsed.host.len);
+ }
+
+ return RenderThread::current()->visited_link_slave()->
+ IsVisited(canon.data(), canon.length());
+}
+
+void DnsPrefetchUrl(const wchar_t* url, int url_length) {
+ if (url_length == 0)
+ return; // Empty URLs have no hostnames.
+
+ // Use big stack buffer to avoid allocation when possible.
+ url_parse::Parsed parsed;
+ url_canon::RawCanonOutput<2048> canon;
+
+ if (!url_util::Canonicalize(url, url_length, NULL, &canon, &parsed))
+ return; // Invalid URLs don't have hostnames.
+
+ // Call for prefetching without creating a std::string().
+ if (parsed.host.is_nonempty())
+ DnsPrefetchCString(canon.data() + parsed.host.begin, parsed.host.len);
+}
+
+void PrecacheUrl(const wchar_t* url, int url_length) {
+ // TBD: jar: Need implementation that loads the targetted URL into our cache.
+ // For now, at least prefetch DNS lookup
+ DnsPrefetchUrl(url, url_length);
+}
+
+void webkit_glue::AppendToLog(const char* file, int line, const char* msg) {
+ logging::LogMessage(file, line).stream() << msg;
+}
+
+bool webkit_glue::GetMimeTypeFromExtension(std::wstring &ext,
+ std::string *mime_type) {
+ if (IsPluginProcess())
+ return mime_util::GetMimeTypeFromExtension(ext, mime_type);
+
+ // The sandbox restricts our access to the registry, so we need to proxy
+ // these calls over to the browser process.
+ DCHECK(mime_type->empty());
+ RenderThread::current()->Send(
+ new ViewHostMsg_GetMimeTypeFromExtension(ext, mime_type));
+ return !mime_type->empty();
+}
+
+bool webkit_glue::GetMimeTypeFromFile(const std::wstring &file_path,
+ std::string *mime_type) {
+ if (IsPluginProcess())
+ return mime_util::GetMimeTypeFromFile(file_path, mime_type);
+
+ // The sandbox restricts our access to the registry, so we need to proxy
+ // these calls over to the browser process.
+ DCHECK(mime_type->empty());
+ RenderThread::current()->Send(
+ new ViewHostMsg_GetMimeTypeFromFile(file_path, mime_type));
+ return !mime_type->empty();
+}
+
+bool webkit_glue::GetPreferredExtensionForMimeType(const std::string& mime_type,
+ std::wstring* ext) {
+ if (IsPluginProcess())
+ return mime_util::GetPreferredExtensionForMimeType(mime_type, ext);
+
+ // The sandbox restricts our access to the registry, so we need to proxy
+ // these calls over to the browser process.
+ DCHECK(ext->empty());
+ RenderThread::current()->Send(
+ new ViewHostMsg_GetPreferredExtensionForMimeType(mime_type, ext));
+ return !ext->empty();
+}
+
+IMLangFontLink2* webkit_glue::GetLangFontLink() {
+ return RenderProcess::GetLangFontLink();
+}
+
+std::wstring webkit_glue::GetLocalizedString(int message_id) {
+ return ResourceBundle::GetSharedInstance().GetLocalizedString(message_id);
+}
+
+std::string webkit_glue::GetDataResource(int resource_id) {
+ return ResourceBundle::GetSharedInstance().GetDataResource(resource_id);
+}
+
+HCURSOR webkit_glue::LoadCursor(int cursor_id) {
+ return ResourceBundle::GetSharedInstance().LoadCursor(cursor_id);
+}
+
+// Clipboard glue
+
+void webkit_glue::ClipboardClear() {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardClear());
+}
+
+void webkit_glue::ClipboardWriteText(const std::wstring& text) {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardWriteText(text));
+}
+
+void webkit_glue::ClipboardWriteHTML(const std::wstring& html,
+ const GURL& url) {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardWriteHTML(html, url));
+}
+
+void webkit_glue::ClipboardWriteBookmark(const std::wstring& title,
+ const GURL& url) {
+ RenderThread::current()->Send(
+ new ViewHostMsg_ClipboardWriteBookmark(title, url));
+}
+
+// Here we need to do some work to marshal the bitmap through shared memory
+void webkit_glue::ClipboardWriteBitmap(const SkBitmap& bitmap) {
+ size_t buf_size = bitmap.getSize();
+ gfx::Size size(bitmap.width(), bitmap.height());
+
+ // Allocate a shared memory buffer to hold the bitmap bits
+ SharedMemory* shared_buf =
+ RenderProcess::AllocSharedMemory(buf_size);
+ if (!shared_buf) {
+ NOTREACHED();
+ return;
+ }
+ if (!shared_buf->Map(buf_size)) {
+ NOTREACHED();
+ return;
+ }
+
+ // Copy the bits into shared memory
+ SkAutoLockPixels bitmap_lock(bitmap);
+ memcpy(shared_buf->memory(), bitmap.getPixels(), buf_size);
+ shared_buf->Unmap();
+
+ // Send the handle over synchronous IPC
+ RenderThread::current()->Send(
+ new ViewHostMsg_ClipboardWriteBitmap(shared_buf->handle(), size));
+
+ // The browser should be done with the bitmap now. It's our job to free
+ // the shared memory.
+ RenderProcess::FreeSharedMemory(shared_buf);
+}
+
+void webkit_glue::ClipboardWriteWebSmartPaste() {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardWriteWebSmartPaste());
+}
+
+bool webkit_glue::ClipboardIsFormatAvailable(unsigned int format) {
+ bool result;
+ RenderThread::current()->Send(
+ new ViewHostMsg_ClipboardIsFormatAvailable(format, &result));
+ return result;
+}
+
+void webkit_glue::ClipboardReadText(std::wstring* result) {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardReadText(result));
+}
+
+void webkit_glue::ClipboardReadAsciiText(std::string* result) {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardReadAsciiText(result));
+}
+
+void webkit_glue::ClipboardReadHTML(std::wstring* markup, GURL* url) {
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardReadHTML(markup, url));
+}
+
+
+bool webkit_glue::GetApplicationDirectory(std::wstring *path) {
+ return PathService::Get(chrome::DIR_APP, path);
+}
+
+GURL webkit_glue::GetInspectorURL() {
+ return GURL("chrome-resource://inspector/inspector.html");
+}
+
+std::string webkit_glue::GetUIResourceProtocol() {
+ return "chrome-resource";
+}
+
+bool webkit_glue::GetExeDirectory(std::wstring *path) {
+ return PathService::Get(base::DIR_EXE, path);
+}
+
+bool webkit_glue::GetPlugins(bool refresh,
+ std::vector<WebPluginInfo>* plugins) {
+ return RenderThread::current()->Send(
+ new ViewHostMsg_GetPlugins(refresh, plugins));
+}
+
+bool webkit_glue::IsPluginRunningInRendererProcess() {
+ return !IsPluginProcess();
+}
+
+bool webkit_glue::EnsureFontLoaded(HFONT font) {
+ LOGFONT logfont;
+ GetObject(font, sizeof(LOGFONT), &logfont);
+ return RenderThread::current()->Send(new ViewHostMsg_LoadFont(logfont));
+}
+
+MONITORINFOEX webkit_glue::GetMonitorInfoForWindow(HWND window) {
+ MONITORINFOEX monitor_info;
+ RenderThread::current()->Send(
+ new ViewHostMsg_GetMonitorInfoForWindow(window, &monitor_info));
+ return monitor_info;
+}
+
+std::wstring webkit_glue::GetWebKitLocale() {
+ // The browser process should have passed the locale to the renderer via the
+ // --lang command line flag.
+ CommandLine parsed_command_line;
+ const std::wstring& lang =
+ parsed_command_line.GetSwitchValue(switches::kLang);
+ DCHECK(!lang.empty());
+ return lang;
+}
+
+#ifndef USING_SIMPLE_RESOURCE_LOADER_BRIDGE
+
+// Each RenderView has a ResourceDispatcher. In unit tests, this function may
+// not work properly since there may be a ResourceDispatcher w/o a RenderView.
+// The WebView's delegate may be null, which typically happens as a WebView is
+// being closed (but it is also possible that it could be null at other times
+// since WebView has a SetDelegate method).
+static ResourceDispatcher* GetResourceDispatcher(WebFrame* frame) {
+ WebViewDelegate* d = frame->GetView()->GetDelegate();
+ return d ? static_cast<RenderView*>(d)->resource_dispatcher() : NULL;
+}
+
+// static factory function
+ResourceLoaderBridge* ResourceLoaderBridge::Create(
+ WebFrame* webframe,
+ const std::string& method,
+ const GURL& url,
+ const GURL& policy_url,
+ const GURL& referrer,
+ const std::string& headers,
+ int load_flags,
+ int origin_pid,
+ ResourceType::Type resource_type,
+ bool mixed_content) {
+ // TODO(darin): we need to eliminate the webframe parameter because webkit
+ // does not always supply it (see ResourceHandle::loadResourceSynchronously).
+ // Instead we should add context to ResourceRequest, which will be easy to do
+ // once we merge to the latest WebKit (r23806 at least).
+ if (!webframe) {
+ NOTREACHED() << "no webframe";
+ return NULL;
+ }
+ ResourceDispatcher* dispatcher = GetResourceDispatcher(webframe);
+ if (!dispatcher) {
+ DLOG(WARNING) << "no resource dispatcher";
+ return NULL;
+ }
+ return dispatcher->CreateBridge(method, url, policy_url, referrer, headers,
+ load_flags, origin_pid, resource_type,
+ mixed_content, 0);
+}
+
+void SetCookie(const GURL& url, const GURL& policy_url,
+ const std::string& cookie) {
+ RenderThread::current()->Send(new ViewHostMsg_SetCookie(url, policy_url,
+ cookie));
+}
+
+std::string GetCookies(const GURL& url, const GURL& policy_url) {
+ std::string cookies;
+ RenderThread::current()->Send(new ViewHostMsg_GetCookies(url, policy_url,
+ &cookies));
+ return cookies;
+}
+
+void NotifyCacheStats() {
+ // Update the browser about our cache
+ // NOTE: Since this can be called from the plugin process, we might not have
+ // a RenderThread. Do nothing in that case.
+ if (RenderThread::current())
+ RenderThread::current()->InformHostOfCacheStatsLater();
+}
+
+#endif // !USING_SIMPLE_RESOURCE_LOADER_BRIDGE
+
+} // namespace webkit_glue