Branch CEF3 files from /branches/cef3 to /trunk/cef3 (issue #564).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@571 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2012-04-03 01:34:16 +00:00
parent b568f160d9
commit 34adee805c
516 changed files with 83249 additions and 0 deletions

View File

@@ -0,0 +1,638 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/renderer/browser_impl.h"
#include <string>
#include <vector>
#include "libcef/common/cef_messages.h"
#include "libcef/common/content_client.h"
#include "libcef/common/process_message_impl.h"
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/renderer/thread_util.h"
#include "libcef/renderer/webkit_glue.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view.h"
#include "net/http/http_util.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "webkit/glue/webkit_glue.h"
using WebKit::WebFrame;
using WebKit::WebScriptSource;
using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebView;
namespace {
const int64 kInvalidBrowserId = -1;
const int64 kInvalidFrameId = -1;
} // namespace
// CefBrowserImpl static methods.
// -----------------------------------------------------------------------------
// static
CefRefPtr<CefBrowserImpl> CefBrowserImpl::GetBrowserForView(
content::RenderView* view) {
return CefContentRendererClient::Get()->GetBrowserForView(view);
}
// static
CefRefPtr<CefBrowserImpl> CefBrowserImpl::GetBrowserForMainFrame(
WebKit::WebFrame* frame) {
return CefContentRendererClient::Get()->GetBrowserForMainFrame(frame);
}
// CefBrowser methods.
// -----------------------------------------------------------------------------
CefRefPtr<CefBrowserHost> CefBrowserImpl::GetHost() {
NOTREACHED() << "GetHost cannot be called from the render process";
return NULL;
}
bool CefBrowserImpl::CanGoBack() {
CEF_REQUIRE_RT_RETURN(false);
return webkit_glue::CanGoBackOrForward(render_view()->GetWebView(), -1);
}
void CefBrowserImpl::GoBack() {
CEF_REQUIRE_RT_RETURN_VOID();
webkit_glue::GoBackOrForward(render_view()->GetWebView(), -1);
}
bool CefBrowserImpl::CanGoForward() {
CEF_REQUIRE_RT_RETURN(false);
return webkit_glue::CanGoBackOrForward(render_view()->GetWebView(), 1);
}
void CefBrowserImpl::GoForward() {
CEF_REQUIRE_RT_RETURN_VOID();
webkit_glue::GoBackOrForward(render_view()->GetWebView(), 1);
}
bool CefBrowserImpl::IsLoading() {
CEF_REQUIRE_RT_RETURN(false);
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
return render_view()->GetWebView()->mainFrame()->isLoading();
return false;
}
void CefBrowserImpl::Reload() {
CEF_REQUIRE_RT_RETURN_VOID();
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
render_view()->GetWebView()->mainFrame()->reload(false);
}
void CefBrowserImpl::ReloadIgnoreCache() {
CEF_REQUIRE_RT_RETURN_VOID();
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
render_view()->GetWebView()->mainFrame()->reload(true);
}
void CefBrowserImpl::StopLoad() {
CEF_REQUIRE_RT_RETURN_VOID();
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
render_view()->GetWebView()->mainFrame()->stopLoading();
}
int CefBrowserImpl::GetIdentifier() {
CEF_REQUIRE_RT_RETURN(0);
return browser_window_id();
}
bool CefBrowserImpl::IsPopup() {
CEF_REQUIRE_RT_RETURN(false);
return is_popup_;
}
bool CefBrowserImpl::HasDocument() {
CEF_REQUIRE_RT_RETURN(false);
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
return !render_view()->GetWebView()->mainFrame()->document().isNull();
return false;
}
CefRefPtr<CefFrame> CefBrowserImpl::GetMainFrame() {
CEF_REQUIRE_RT_RETURN(NULL);
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
return GetWebFrameImpl(render_view()->GetWebView()->mainFrame()).get();
return NULL;
}
CefRefPtr<CefFrame> CefBrowserImpl::GetFocusedFrame() {
CEF_REQUIRE_RT_RETURN(NULL);
if (render_view()->GetWebView() &&
render_view()->GetWebView()->focusedFrame()) {
return GetWebFrameImpl(render_view()->GetWebView()->focusedFrame()).get();
}
return NULL;
}
CefRefPtr<CefFrame> CefBrowserImpl::GetFrame(int64 identifier) {
CEF_REQUIRE_RT_RETURN(NULL);
return GetWebFrameImpl(identifier).get();
}
CefRefPtr<CefFrame> CefBrowserImpl::GetFrame(const CefString& name) {
CEF_REQUIRE_RT_RETURN(NULL);
if (render_view()->GetWebView()) {
WebFrame* frame =
render_view()->GetWebView()->findFrameByName(name.ToString16());
if (frame)
return GetWebFrameImpl(frame).get();
}
return NULL;
}
size_t CefBrowserImpl::GetFrameCount() {
CEF_REQUIRE_RT_RETURN(0);
int count = 0;
if (render_view()->GetWebView()) {
WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
if (main_frame) {
WebFrame* cur = main_frame;
do {
count++;
cur = cur->traverseNext(true);
} while (cur != main_frame);
}
}
return count;
}
void CefBrowserImpl::GetFrameIdentifiers(std::vector<int64>& identifiers) {
CEF_REQUIRE_RT_RETURN_VOID();
if (render_view()->GetWebView()) {
WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
if (main_frame) {
WebFrame* cur = main_frame;
do {
identifiers.push_back(cur->identifier());
cur = cur->traverseNext(true);
} while (cur != main_frame);
}
}
}
void CefBrowserImpl::GetFrameNames(std::vector<CefString>& names) {
CEF_REQUIRE_RT_RETURN_VOID();
if (render_view()->GetWebView()) {
WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
if (main_frame) {
WebFrame* cur = main_frame;
do {
names.push_back(CefString(cur->name().utf8()));
cur = cur->traverseNext(true);
} while (cur != main_frame);
}
}
}
bool CefBrowserImpl::SendProcessMessage(CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) {
DCHECK_EQ(PID_BROWSER, target_process);
DCHECK(message.get());
Cef_Request_Params params;
CefProcessMessageImpl* impl =
static_cast<CefProcessMessageImpl*>(message.get());
if (impl->CopyTo(params)) {
DCHECK(!params.name.empty());
params.frame_id = -1;
params.user_initiated = true;
params.request_id = -1;
params.expect_response = false;
return Send(new CefHostMsg_Request(routing_id(), params));
}
return false;
}
// CefBrowserImpl public methods.
// -----------------------------------------------------------------------------
CefBrowserImpl::CefBrowserImpl(content::RenderView* render_view)
: content::RenderViewObserver(render_view),
browser_window_id_(kInvalidBrowserId),
is_popup_(false),
last_focused_frame_id_(kInvalidFrameId) {
}
CefBrowserImpl::~CefBrowserImpl() {
}
void CefBrowserImpl::LoadRequest(const CefMsg_LoadRequest_Params& params) {
CefRefPtr<CefFrameImpl> framePtr = GetWebFrameImpl(params.frame_id);
if (!framePtr.get())
return;
WebFrame* web_frame = framePtr->web_frame();
WebKit::WebURLRequest request(params.url);
// DidCreateDataSource checks for this value.
request.setRequestorID(-1);
if (!params.method.empty())
request.setHTTPMethod(ASCIIToUTF16(params.method));
if (params.referrer.is_valid()) {
WebString referrer = WebKit::WebSecurityPolicy::generateReferrerHeader(
static_cast<WebKit::WebReferrerPolicy>(params.referrer_policy),
params.url,
WebString::fromUTF8(params.referrer.spec()));
if (!referrer.isEmpty())
request.setHTTPHeaderField(WebString::fromUTF8("Referer"), referrer);
}
if (params.first_party_for_cookies.is_valid())
request.setFirstPartyForCookies(params.first_party_for_cookies);
if (!params.headers.empty()) {
for (net::HttpUtil::HeadersIterator i(params.headers.begin(),
params.headers.end(), "\n");
i.GetNext(); ) {
request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
WebString::fromUTF8(i.values()));
}
}
if (params.upload_data.get()) {
string16 method = request.httpMethod();
if (method == ASCIIToUTF16("GET") || method == ASCIIToUTF16("HEAD"))
request.setHTTPMethod(ASCIIToUTF16("POST"));
if (request.httpHeaderField(ASCIIToUTF16("Content-Type")).length() == 0) {
request.setHTTPHeaderField(
ASCIIToUTF16("Content-Type"),
ASCIIToUTF16("application/x-www-form-urlencoded"));
}
WebKit::WebHTTPBody body;
body.initialize();
std::vector<net::UploadData::Element>* elements =
params.upload_data->elements();
std::vector<net::UploadData::Element>::const_iterator it =
elements->begin();
for (; it != elements->end(); ++it) {
const net::UploadData::Element& element = *it;
if (element.type() == net::UploadData::TYPE_BYTES) {
WebKit::WebData data;
data.assign(std::string(element.bytes().begin(),
element.bytes().end()).c_str(),
element.bytes().size());
body.appendData(data);
} else if (element.type() == net::UploadData::TYPE_FILE) {
body.appendFile(webkit_glue::FilePathToWebString(element.file_path()));
} else {
NOTREACHED();
}
}
request.setHTTPBody(body);
}
web_frame->loadRequest(request);
}
CefRefPtr<CefFrameImpl> CefBrowserImpl::GetWebFrameImpl(
WebKit::WebFrame* frame) {
DCHECK(frame);
int64 frame_id = frame->identifier();
// Frames are re-used between page loads. Only add the frame to the map once.
FrameMap::const_iterator it = frames_.find(frame_id);
if (it != frames_.end())
return it->second;
CefRefPtr<CefFrameImpl> framePtr(new CefFrameImpl(this, frame));
frames_.insert(std::make_pair(frame_id, framePtr));
int64 parent_id = frame->parent() == NULL ?
kInvalidFrameId : frame->parent()->identifier();
string16 name = frame->name();
// Notify the browser that the frame has been identified.
Send(new CefHostMsg_FrameIdentified(routing_id(), frame_id, parent_id, name));
return framePtr;
}
CefRefPtr<CefFrameImpl> CefBrowserImpl::GetWebFrameImpl(int64 frame_id) {
if (frame_id == kInvalidFrameId) {
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame())
return GetWebFrameImpl(render_view()->GetWebView()->mainFrame());
return NULL;
}
// Check if we already know about the frame.
FrameMap::const_iterator it = frames_.find(frame_id);
if (it != frames_.end())
return it->second;
if (render_view()->GetWebView()) {
// Check if the frame exists but we don't know about it yet.
WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
if (main_frame) {
WebFrame* cur = main_frame;
do {
if (cur->identifier() == frame_id)
return GetWebFrameImpl(cur);
cur = cur->traverseNext(true);
} while (cur != main_frame);
}
}
return NULL;
}
// RenderViewObserver methods.
// -----------------------------------------------------------------------------
void CefBrowserImpl::OnDestruct() {
// Notify that the browser window has been destroyed.
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get())
handler->OnBrowserDestroyed(this);
}
CefContentRendererClient::Get()->OnBrowserDestroyed(this);
}
void CefBrowserImpl::DidStartProvisionalLoad(WebKit::WebFrame* frame) {
// Send the frame creation notification if necessary.
GetWebFrameImpl(frame);
}
void CefBrowserImpl::FrameDetached(WebFrame* frame) {
int64 frame_id = frame->identifier();
// Remove the frame from the map.
FrameMap::iterator it = frames_.find(frame_id);
DCHECK(it != frames_.end());
it->second->Detach();
frames_.erase(it);
// Notify the browser that the frame has detached.
Send(new CefHostMsg_FrameDetached(routing_id(), frame_id));
}
void CefBrowserImpl::FocusedNodeChanged(const WebKit::WebNode& node) {
// TODO(cef): This method is being used as a work-around for identifying frame
// focus changes. The ideal approach would be implementating delegation from
// ChromeClientImpl::focusedFrameChanged().
WebFrame* focused_frame = NULL;
// Try to identify the focused frame from the node.
if (!node.isNull()) {
const WebKit::WebDocument& document = node.document();
if (!document.isNull())
focused_frame = document.frame();
}
if (focused_frame == NULL && render_view()->GetWebView()) {
// Try to identify the global focused frame.
focused_frame = render_view()->GetWebView()->focusedFrame();
}
int64 frame_id = kInvalidFrameId;
if (focused_frame != NULL)
frame_id = focused_frame->identifier();
// Don't send a message if the focused frame has not changed.
if (frame_id == last_focused_frame_id_)
return;
last_focused_frame_id_ = frame_id;
Send(new CefHostMsg_FrameFocusChange(routing_id(), frame_id));
}
void CefBrowserImpl::DidCreateDataSource(WebKit::WebFrame* frame,
WebKit::WebDataSource* ds) {
const WebKit::WebURLRequest& request = ds->request();
if (request.requestorID() == -1) {
// Mark the request as browser-initiated so
// RenderViewImpl::decidePolicyForNavigation won't attempt to fork it.
content::DocumentState* document_state =
content::DocumentState::FromDataSource(ds);
document_state->set_navigation_state(
content::NavigationState::CreateBrowserInitiated(-1, -1,
content::PAGE_TRANSITION_LINK));
}
if (frame->parent() == 0) {
GURL url = ds->request().url();
if (!url.is_empty()) {
// Notify that the loading URL has changed.
Send(new CefHostMsg_LoadingURLChange(routing_id(), url));
}
}
}
bool CefBrowserImpl::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CefBrowserImpl, message)
IPC_MESSAGE_HANDLER(CefMsg_UpdateBrowserWindowId,
OnUpdateBrowserWindowId)
IPC_MESSAGE_HANDLER(CefMsg_Request, OnRequest)
IPC_MESSAGE_HANDLER(CefMsg_Response, OnResponse)
IPC_MESSAGE_HANDLER(CefMsg_ResponseAck, OnResponseAck)
IPC_MESSAGE_HANDLER(CefMsg_LoadRequest, LoadRequest)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
// RenderViewObserver::OnMessageReceived message handlers.
// -----------------------------------------------------------------------------
void CefBrowserImpl::OnUpdateBrowserWindowId(int window_id, bool is_popup) {
// This message should only be sent one time.
DCHECK(browser_window_id_ == kInvalidBrowserId);
browser_window_id_ = window_id;
is_popup_ = is_popup;
// Notify that the browser window has been created.
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get())
handler->OnBrowserCreated(this);
}
}
void CefBrowserImpl::OnRequest(const Cef_Request_Params& params) {
bool success = false;
std::string response;
bool expect_response_ack = false;
if (params.user_initiated) {
// Give the user a chance to handle the request.
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefProcessMessageImpl> message(
new CefProcessMessageImpl(const_cast<Cef_Request_Params*>(&params),
false, true));
success = handler->OnProcessMessageRecieved(this, PID_BROWSER,
message.get());
message->Detach(NULL);
}
}
} else if (params.name == "execute-code") {
// Execute code.
CefRefPtr<CefFrameImpl> framePtr = GetWebFrameImpl(params.frame_id);
if (framePtr.get()) {
WebFrame* web_frame = framePtr->web_frame();
if (web_frame) {
DCHECK_EQ(params.arguments.GetSize(), (size_t)4);
bool is_javascript = false;
string16 code, script_url;
int script_start_line = 0;
params.arguments.GetBoolean(0, &is_javascript);
params.arguments.GetString(1, &code);
DCHECK(!code.empty());
params.arguments.GetString(2, &script_url);
DCHECK(!script_url.empty());
params.arguments.GetInteger(3, &script_start_line);
DCHECK_GE(script_start_line, 0);
if (is_javascript) {
web_frame->executeScript(
WebScriptSource(code,
GURL(UTF16ToUTF8(script_url)),
script_start_line));
success = true;
} else {
// TODO(cef): implement support for CSS code.
NOTIMPLEMENTED();
}
}
}
} else if (params.name == "execute-command") {
// Execute command.
CefRefPtr<CefFrameImpl> framePtr = GetWebFrameImpl(params.frame_id);
if (framePtr.get()) {
WebFrame* web_frame = framePtr->web_frame();
if (web_frame) {
DCHECK_EQ(params.arguments.GetSize(), (size_t)1);
string16 command;
params.arguments.GetString(0, &command);
DCHECK(!command.empty());
if (LowerCaseEqualsASCII(command, "getsource")) {
response = web_frame->contentAsMarkup().utf8();
success = true;
} else if (LowerCaseEqualsASCII(command, "gettext")) {
response = UTF16ToUTF8(webkit_glue::DumpDocumentText(web_frame));
success = true;
} else if (web_frame->executeCommand(command)) {
success = true;
}
}
}
} else if (params.name == "load-string") {
// Load a string.
CefRefPtr<CefFrameImpl> framePtr = GetWebFrameImpl(params.frame_id);
if (framePtr.get()) {
WebFrame* web_frame = framePtr->web_frame();
if (web_frame) {
DCHECK_EQ(params.arguments.GetSize(), (size_t)2);
string16 string, url;
params.arguments.GetString(0, &string);
DCHECK(!string.empty());
params.arguments.GetString(1, &url);
DCHECK(!url.empty());
web_frame->loadHTMLString(UTF16ToUTF8(string), GURL(UTF16ToUTF8(url)));
}
}
} else {
// Invalid request.
NOTREACHED();
}
if (params.expect_response) {
DCHECK_GE(params.request_id, 0);
// Send a response to the browser.
Cef_Response_Params response_params;
response_params.request_id = params.request_id;
response_params.success = success;
response_params.response = response;
response_params.expect_response_ack = expect_response_ack;
Send(new CefHostMsg_Response(routing_id(), response_params));
}
}
void CefBrowserImpl::OnResponse(const Cef_Response_Params& params) {
response_manager_.RunHandler(params);
if (params.expect_response_ack)
Send(new CefHostMsg_ResponseAck(routing_id(), params.request_id));
}
void CefBrowserImpl::OnResponseAck(int request_id) {
response_manager_.RunAckHandler(request_id);
}

View File

@@ -0,0 +1,125 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_BROWSER_IMPL_H_
#define CEF_LIBCEF_RENDERER_BROWSER_IMPL_H_
#pragma once
#include <map>
#include <string>
#include <vector>
#include "include/cef_browser.h"
#include "include/cef_client.h"
#include "libcef/common/response_manager.h"
#include "libcef/renderer/frame_impl.h"
#include "content/public/renderer/render_view_observer.h"
class GURL;
struct CefMsg_LoadRequest_Params;
struct Cef_Request_Params;
struct Cef_Response_Params;
class CefContentRendererClient;
namespace base {
class ListValue;
}
namespace WebKit {
class WebFrame;
}
// Renderer plumbing for CEF features. There is a one-to-one relationship
// between RenderView on the renderer side and RenderViewHost on the browser
// side.
//
// RenderViewObserver: Interface for observing RenderView notifications and IPC
// messages. IPC messages received by the RenderView will be forwarded to this
// RenderViewObserver implementation. IPC messages sent using
// RenderViewObserver::Send() will be forwarded to the RenderView. Use
// RenderViewObserver::routing_id() when sending IPC messages.
class CefBrowserImpl : public CefBrowser,
public content::RenderViewObserver {
public:
// Returns the browser associated with the specified RenderView.
static CefRefPtr<CefBrowserImpl> GetBrowserForView(content::RenderView* view);
// Returns the browser associated with the specified main WebFrame.
static CefRefPtr<CefBrowserImpl> GetBrowserForMainFrame(
WebKit::WebFrame* frame);
// CefBrowser methods.
virtual CefRefPtr<CefBrowserHost> GetHost() OVERRIDE;
virtual bool CanGoBack() OVERRIDE;
virtual void GoBack() OVERRIDE;
virtual bool CanGoForward() OVERRIDE;
virtual void GoForward() OVERRIDE;
virtual bool IsLoading() OVERRIDE;
virtual void Reload() OVERRIDE;
virtual void ReloadIgnoreCache() OVERRIDE;
virtual void StopLoad() OVERRIDE;
virtual int GetIdentifier() OVERRIDE;
virtual bool IsPopup() OVERRIDE;
virtual bool HasDocument() OVERRIDE;
virtual CefRefPtr<CefFrame> GetMainFrame() OVERRIDE;
virtual CefRefPtr<CefFrame> GetFocusedFrame() OVERRIDE;
virtual CefRefPtr<CefFrame> GetFrame(int64 identifier) OVERRIDE;
virtual CefRefPtr<CefFrame> GetFrame(const CefString& name) OVERRIDE;
virtual size_t GetFrameCount() OVERRIDE;
virtual void GetFrameIdentifiers(std::vector<int64>& identifiers) OVERRIDE;
virtual void GetFrameNames(std::vector<CefString>& names) OVERRIDE;
virtual bool SendProcessMessage(
CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) OVERRIDE;
explicit CefBrowserImpl(content::RenderView* render_view);
virtual ~CefBrowserImpl();
void LoadRequest(const CefMsg_LoadRequest_Params& params);
// Returns the matching WebFrameImpl reference or creates a new one.
CefRefPtr<CefFrameImpl> GetWebFrameImpl(WebKit::WebFrame* frame);
CefRefPtr<CefFrameImpl> GetWebFrameImpl(int64 frame_id);
int browser_window_id() const { return browser_window_id_; }
content::RenderView* render_view() {
return content::RenderViewObserver::render_view();
}
private:
// RenderViewObserver methods.
virtual void OnDestruct() OVERRIDE;
virtual void DidStartProvisionalLoad(WebKit::WebFrame* frame) OVERRIDE;
virtual void FrameDetached(WebKit::WebFrame* frame) OVERRIDE;
virtual void FocusedNodeChanged(const WebKit::WebNode& node) OVERRIDE;
virtual void DidCreateDataSource(WebKit::WebFrame* frame,
WebKit::WebDataSource* ds) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// RenderViewObserver::OnMessageReceived message handlers.
void OnUpdateBrowserWindowId(int window_id, bool is_popup);
void OnRequest(const Cef_Request_Params& params);
void OnResponse(const Cef_Response_Params& params);
void OnResponseAck(int request_id);
// Id number of browser window which RenderView is attached to.
int browser_window_id_;
bool is_popup_;
// Id of the last frame that had focus.
int64 last_focused_frame_id_;
// Map of unique frame ids to CefFrameImpl references.
typedef std::map<int64, CefRefPtr<CefFrameImpl> > FrameMap;
FrameMap frames_;
// Manages response registrations.
CefResponseManager response_manager_;
IMPLEMENT_REFCOUNTING(CefBrowserImpl);
DISALLOW_COPY_AND_ASSIGN(CefBrowserImpl);
};
#endif // CEF_LIBCEF_RENDERER_BROWSER_IMPL_H_

View File

@@ -0,0 +1,264 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/content_client.h"
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/render_message_filter.h"
#include "libcef/renderer/render_process_observer.h"
#include "libcef/renderer/thread_util.h"
#include "libcef/renderer/v8_impl.h"
#include "content/common/child_thread.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "ipc/ipc_sync_channel.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "v8/include/v8.h"
CefContentRendererClient::CefContentRendererClient() {
}
CefContentRendererClient::~CefContentRendererClient() {
}
// static
CefContentRendererClient* CefContentRendererClient::Get() {
return static_cast<CefContentRendererClient*>(
content::GetContentClient()->renderer());
}
CefRefPtr<CefBrowserImpl> CefContentRendererClient::GetBrowserForView(
content::RenderView* view) {
CEF_REQUIRE_RT_RETURN(NULL);
BrowserMap::const_iterator it = browsers_.find(view);
if (it != browsers_.end())
return it->second;
return NULL;
}
CefRefPtr<CefBrowserImpl> CefContentRendererClient::GetBrowserForMainFrame(
WebKit::WebFrame* frame) {
CEF_REQUIRE_RT_RETURN(NULL);
BrowserMap::const_iterator it = browsers_.begin();
for (; it != browsers_.end(); ++it) {
content::RenderView* render_view = it->second->render_view();
if (render_view && render_view->GetWebView() &&
render_view->GetWebView()->mainFrame() == frame) {
return it->second;
}
}
return NULL;
}
void CefContentRendererClient::OnBrowserDestroyed(CefBrowserImpl* browser) {
BrowserMap::iterator it = browsers_.begin();
for (; it != browsers_.end(); ++it) {
if (it->second.get() == browser) {
browsers_.erase(it);
return;
}
}
// No browser was found in the map.
NOTREACHED();
}
void CefContentRendererClient::RenderThreadStarted() {
render_loop_ = base::MessageLoopProxy::current();
observer_.reset(new CefRenderProcessObserver());
content::RenderThread* thread = content::RenderThread::Get();
thread->AddObserver(observer_.get());
thread->GetChannel()->AddFilter(new CefRenderMessageFilter);
thread->Send(new CefProcessHostMsg_RenderThreadStarted);
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (application.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (handler.get())
handler->OnRenderThreadCreated();
}
}
void CefContentRendererClient::RenderViewCreated(
content::RenderView* render_view) {
CefRefPtr<CefBrowserImpl> browser = new CefBrowserImpl(render_view);
browsers_.insert(std::make_pair(render_view, browser));
}
void CefContentRendererClient::SetNumberOfViews(int number_of_views) {
}
SkBitmap* CefContentRendererClient::GetSadPluginBitmap() {
return NULL;
}
std::string CefContentRendererClient::GetDefaultEncoding() {
return std::string();
}
bool CefContentRendererClient::OverrideCreatePlugin(
content::RenderView* render_view,
WebKit::WebFrame* frame,
const WebKit::WebPluginParams& params,
WebKit::WebPlugin** plugin) {
return false;
}
bool CefContentRendererClient::HasErrorPage(int http_status_code,
std::string* error_domain) {
return false;
}
void CefContentRendererClient::GetNavigationErrorStrings(
const WebKit::WebURLRequest& failed_request,
const WebKit::WebURLError& error,
std::string* error_html,
string16* error_description) {
}
webkit_media::WebMediaPlayerImpl*
CefContentRendererClient::OverrideCreateWebMediaPlayer(
content::RenderView* render_view,
WebKit::WebFrame* frame,
WebKit::WebMediaPlayerClient* client,
base::WeakPtr<webkit_media::WebMediaPlayerDelegate> delegate,
media::FilterCollection* collection,
WebKit::WebAudioSourceProvider* audio_source_provider,
media::MessageLoopFactory* message_loop_factory,
webkit_media::MediaStreamClient* media_stream_client,
media::MediaLog* media_log) {
return NULL;
}
bool CefContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
return true;
}
bool CefContentRendererClient::AllowPopup(const GURL& creator) {
return false;
}
bool CefContentRendererClient::ShouldFork(WebKit::WebFrame* frame,
const GURL& url,
bool is_initial_navigation,
bool* send_referrer) {
return false;
}
bool CefContentRendererClient::WillSendRequest(WebKit::WebFrame* frame,
const GURL& url,
GURL* new_url) {
return false;
}
bool CefContentRendererClient::ShouldPumpEventsDuringCookieMessage() {
return false;
}
void CefContentRendererClient::DidCreateScriptContext(
WebKit::WebFrame* frame, v8::Handle<v8::Context> context,
int extension_group, int world_id) {
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (!application.get())
return;
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (!handler.get())
return;
CefRefPtr<CefBrowserImpl> browserPtr =
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
DCHECK(browserPtr.get());
if (!browserPtr.get())
return;
CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
v8::HandleScope handle_scope;
v8::Context::Scope scope(context);
CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(context));
handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
}
void CefContentRendererClient::WillReleaseScriptContext(
WebKit::WebFrame* frame, v8::Handle<v8::Context> context, int world_id) {
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (!application.get())
return;
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (!handler.get())
return;
CefRefPtr<CefBrowserImpl> browserPtr =
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
DCHECK(browserPtr.get());
if (!browserPtr.get())
return;
CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
v8::HandleScope handle_scope;
v8::Context::Scope scope(context);
CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(context));
handler->OnContextReleased(browserPtr.get(), framePtr.get(), contextPtr);
}
unsigned long long CefContentRendererClient::VisitedLinkHash(
const char* canonical_url, size_t length) {
return 0LL;
}
bool CefContentRendererClient::IsLinkVisited(unsigned long long link_hash) {
return false;
}
void CefContentRendererClient::PrefetchHostName(
const char* hostname, size_t length) {
}
bool CefContentRendererClient::ShouldOverridePageVisibilityState(
const content::RenderView* render_view,
WebKit::WebPageVisibilityState* override_state) const {
return false;
}
bool CefContentRendererClient::HandleGetCookieRequest(
content::RenderView* sender,
const GURL& url,
const GURL& first_party_for_cookies,
std::string* cookies) {
return false;
}
bool CefContentRendererClient::HandleSetCookieRequest(
content::RenderView* sender,
const GURL& url,
const GURL& first_party_for_cookies,
const std::string& value) {
return false;
}
void CefContentRendererClient::RegisterPPAPIInterfaceFactories(
webkit::ppapi::PpapiInterfaceFactoryManager* factory_manager) {
}

View File

@@ -0,0 +1,115 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_CONTENT_RENDERER_CLIENT_H_
#define CEF_LIBCEF_RENDERER_CONTENT_RENDERER_CLIENT_H_
#pragma once
#include <map>
#include <set>
#include <string>
#include "libcef/renderer/browser_impl.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop_proxy.h"
#include "content/public/renderer/content_renderer_client.h"
class CefRenderProcessObserver;
class CefContentRendererClient : public content::ContentRendererClient {
public:
CefContentRendererClient();
virtual ~CefContentRendererClient();
// Returns the singleton CefContentRendererClient instance.
static CefContentRendererClient* Get();
// Returns the browser associated with the specified RenderView.
CefRefPtr<CefBrowserImpl> GetBrowserForView(content::RenderView* view);
// Returns the browser associated with the specified main WebFrame.
CefRefPtr<CefBrowserImpl> GetBrowserForMainFrame(WebKit::WebFrame* frame);
// Called from CefBrowserImpl::OnDestruct().
void OnBrowserDestroyed(CefBrowserImpl* browser);
// Render thread message loop proxy.
base::MessageLoopProxy* render_loop() const { return render_loop_.get(); }
private:
// ContentRendererClient implementation.
virtual void RenderThreadStarted() OVERRIDE;
virtual void RenderViewCreated(content::RenderView* render_view) OVERRIDE;
virtual void SetNumberOfViews(int number_of_views) OVERRIDE;
virtual SkBitmap* GetSadPluginBitmap() OVERRIDE;
virtual std::string GetDefaultEncoding() OVERRIDE;
virtual bool OverrideCreatePlugin(
content::RenderView* render_view,
WebKit::WebFrame* frame,
const WebKit::WebPluginParams& params,
WebKit::WebPlugin** plugin) OVERRIDE;
virtual bool HasErrorPage(int http_status_code,
std::string* error_domain) OVERRIDE;
virtual void GetNavigationErrorStrings(
const WebKit::WebURLRequest& failed_request,
const WebKit::WebURLError& error,
std::string* error_html,
string16* error_description) OVERRIDE;
virtual webkit_media::WebMediaPlayerImpl* OverrideCreateWebMediaPlayer(
content::RenderView* render_view,
WebKit::WebFrame* frame,
WebKit::WebMediaPlayerClient* client,
base::WeakPtr<webkit_media::WebMediaPlayerDelegate> delegate,
media::FilterCollection* collection,
WebKit::WebAudioSourceProvider* audio_source_provider,
media::MessageLoopFactory* message_loop_factory,
webkit_media::MediaStreamClient* media_stream_client,
media::MediaLog* media_log) OVERRIDE;
virtual bool RunIdleHandlerWhenWidgetsHidden() OVERRIDE;
virtual bool AllowPopup(const GURL& creator) OVERRIDE;
virtual bool ShouldFork(WebKit::WebFrame* frame,
const GURL& url,
bool is_initial_navigation,
bool* send_referrer) OVERRIDE;
virtual bool WillSendRequest(WebKit::WebFrame* frame,
const GURL& url,
GURL* new_url) OVERRIDE;
virtual bool ShouldPumpEventsDuringCookieMessage() OVERRIDE;
virtual void DidCreateScriptContext(WebKit::WebFrame* frame,
v8::Handle<v8::Context> context,
int extension_group,
int world_id) OVERRIDE;
virtual void WillReleaseScriptContext(WebKit::WebFrame* frame,
v8::Handle<v8::Context> context,
int world_id) OVERRIDE;
virtual unsigned long long VisitedLinkHash(const char* canonical_url,
size_t length) OVERRIDE;
virtual bool IsLinkVisited(unsigned long long link_hash) OVERRIDE;
virtual void PrefetchHostName(const char* hostname, size_t length) OVERRIDE;
virtual bool ShouldOverridePageVisibilityState(
const content::RenderView* render_view,
WebKit::WebPageVisibilityState* override_state) const OVERRIDE;
virtual bool HandleGetCookieRequest(content::RenderView* sender,
const GURL& url,
const GURL& first_party_for_cookies,
std::string* cookies) OVERRIDE;
virtual bool HandleSetCookieRequest(content::RenderView* sender,
const GURL& url,
const GURL& first_party_for_cookies,
const std::string& value) OVERRIDE;
virtual void RegisterPPAPIInterfaceFactories(
webkit::ppapi::PpapiInterfaceFactoryManager* factory_manager) OVERRIDE;
scoped_refptr<base::MessageLoopProxy> render_loop_;
scoped_ptr<CefRenderProcessObserver> observer_;
// Map of RenderView pointers to CefBrowserImpl references.
typedef std::map<content::RenderView*, CefRefPtr<CefBrowserImpl> > BrowserMap;
BrowserMap browsers_;
};
#endif // CEF_LIBCEF_RENDERER_CONTENT_RENDERER_CLIENT_H_

View File

@@ -0,0 +1,246 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#include "libcef/renderer/frame_impl.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/http_header_utils.h"
#include "libcef/common/request_impl.h"
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/thread_util.h"
#include "libcef/renderer/v8_impl.h"
#include "libcef/renderer/webkit_glue.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
#include "webkit/glue/webkit_glue.h"
using WebKit::WebString;
CefFrameImpl::CefFrameImpl(CefBrowserImpl* browser,
WebKit::WebFrame* frame)
: browser_(browser),
frame_(frame),
frame_id_(frame->identifier()) {
}
CefFrameImpl::~CefFrameImpl() {
}
bool CefFrameImpl::IsValid() {
CEF_REQUIRE_RT_RETURN(false);
return (frame_ != NULL);
}
void CefFrameImpl::Undo() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("Undo"));
}
void CefFrameImpl::Redo() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("Redo"));
}
void CefFrameImpl::Cut() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("Cut"));
}
void CefFrameImpl::Copy() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("Copy"));
}
void CefFrameImpl::Paste() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("Paste"));
}
void CefFrameImpl::Delete() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("Delete"));
}
void CefFrameImpl::SelectAll() {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_)
frame_->executeCommand(WebString::fromUTF8("SelectAll"));
}
void CefFrameImpl::ViewSource() {
NOTREACHED() << "ViewSource cannot be called from the renderer process";
}
void CefFrameImpl::GetSource(CefRefPtr<CefStringVisitor> visitor) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
CefString content = std::string(frame_->contentAsMarkup().utf8());
visitor->Visit(content);
}
}
void CefFrameImpl::GetText(CefRefPtr<CefStringVisitor> visitor) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
CefString content = webkit_glue::DumpDocumentText(frame_);
visitor->Visit(content);
}
}
void CefFrameImpl::LoadRequest(CefRefPtr<CefRequest> request) {
CEF_REQUIRE_RT_RETURN_VOID();
if (!browser_)
return;
CefMsg_LoadRequest_Params params;
params.url = GURL(std::string(request->GetURL()));
params.method = request->GetMethod();
params.frame_id = frame_id_;
params.first_party_for_cookies =
GURL(std::string(request->GetFirstPartyForCookies()));
CefRequest::HeaderMap headerMap;
request->GetHeaderMap(headerMap);
if (!headerMap.empty())
params.headers = HttpHeaderUtils::GenerateHeaders(headerMap);
CefRefPtr<CefPostData> postData = request->GetPostData();
if (postData.get()) {
CefPostDataImpl* impl = static_cast<CefPostDataImpl*>(postData.get());
params.upload_data = new net::UploadData();
impl->Get(*params.upload_data.get());
}
params.load_flags = request->GetFlags();
browser_->LoadRequest(params);
}
void CefFrameImpl::LoadURL(const CefString& url) {
CEF_REQUIRE_RT_RETURN_VOID();
if (!browser_)
return;
CefMsg_LoadRequest_Params params;
params.url = GURL(url.ToString());
params.method = "GET";
params.frame_id = frame_id_;
browser_->LoadRequest(params);
}
void CefFrameImpl::LoadString(const CefString& string,
const CefString& url) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
GURL gurl = GURL(url.ToString());
frame_->loadHTMLString(string.ToString(), gurl);
}
}
void CefFrameImpl::ExecuteJavaScript(const CefString& jsCode,
const CefString& scriptUrl,
int startLine) {
CEF_REQUIRE_RT_RETURN_VOID();
if (frame_) {
GURL gurl = GURL(scriptUrl.ToString());
frame_->executeScript(
WebKit::WebScriptSource(jsCode.ToString16(), gurl, startLine));
}
}
bool CefFrameImpl::IsMain() {
CEF_REQUIRE_RT_RETURN(false);
if (frame_)
return (frame_->parent() == NULL);
return false;
}
bool CefFrameImpl::IsFocused() {
CEF_REQUIRE_RT_RETURN(false);
if (frame_ && frame_->view())
return (frame_->view()->focusedFrame() == frame_);
return false;
}
CefString CefFrameImpl::GetName() {
CefString name;
CEF_REQUIRE_RT_RETURN(name);
if (frame_)
name = frame_->name();
return name;
}
int64 CefFrameImpl::GetIdentifier() {
CEF_REQUIRE_RT_RETURN(0);
return frame_id_;
}
CefRefPtr<CefFrame> CefFrameImpl::GetParent() {
CEF_REQUIRE_RT_RETURN(NULL);
if (frame_) {
WebKit::WebFrame* parent = frame_->parent();
if (parent)
return browser_->GetWebFrameImpl(parent).get();
}
return NULL;
}
CefString CefFrameImpl::GetURL() {
CefString url;
CEF_REQUIRE_RT_RETURN(url);
if (frame_) {
GURL gurl = frame_->document().url();
url = gurl.spec();
}
return url;
}
CefRefPtr<CefBrowser> CefFrameImpl::GetBrowser() {
CEF_REQUIRE_RT_RETURN(NULL);
return browser_;
}
CefRefPtr<CefV8Context> CefFrameImpl::GetV8Context() {
CEF_REQUIRE_RT_RETURN(NULL);
if (frame_) {
v8::HandleScope handle_scope;
return new CefV8ContextImpl(webkit_glue::GetV8Context(frame_));
} else {
return NULL;
}
}
void CefFrameImpl::Detach() {
browser_ = NULL;
frame_ = NULL;
}

View File

@@ -0,0 +1,69 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_FRAME_IMPL_H_
#define CEF_LIBCEF_RENDERER_FRAME_IMPL_H_
#pragma once
#include <string>
#include "include/cef_frame.h"
#include "include/cef_v8.h"
class CefBrowserImpl;
namespace WebKit {
class WebFrame;
}
// Implementation of CefFrame. CefFrameImpl objects are owned by the
// CefBrowerImpl and will be detached when the browser is notified that the
// associated renderer WebFrame will close.
class CefFrameImpl : public CefFrame {
public:
CefFrameImpl(CefBrowserImpl* browser,
WebKit::WebFrame* frame);
virtual ~CefFrameImpl();
// CefFrame implementation.
virtual bool IsValid() OVERRIDE;
virtual void Undo() OVERRIDE;
virtual void Redo() OVERRIDE;
virtual void Cut() OVERRIDE;
virtual void Copy() OVERRIDE;
virtual void Paste() OVERRIDE;
virtual void Delete() OVERRIDE;
virtual void SelectAll() OVERRIDE;
virtual void ViewSource() OVERRIDE;
virtual void GetSource(CefRefPtr<CefStringVisitor> visitor) OVERRIDE;
virtual void GetText(CefRefPtr<CefStringVisitor> visitor) OVERRIDE;
virtual void LoadRequest(CefRefPtr<CefRequest> request) OVERRIDE;
virtual void LoadURL(const CefString& url) OVERRIDE;
virtual void LoadString(const CefString& string,
const CefString& url) OVERRIDE;
virtual void ExecuteJavaScript(const CefString& jsCode,
const CefString& scriptUrl,
int startLine) OVERRIDE;
virtual bool IsMain() OVERRIDE;
virtual bool IsFocused() OVERRIDE;
virtual CefString GetName() OVERRIDE;
virtual int64 GetIdentifier() OVERRIDE;
virtual CefRefPtr<CefFrame> GetParent() OVERRIDE;
virtual CefString GetURL() OVERRIDE;
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual CefRefPtr<CefV8Context> GetV8Context() OVERRIDE;
void Detach();
WebKit::WebFrame* web_frame() const { return frame_; }
protected:
CefBrowserImpl* browser_;
WebKit::WebFrame* frame_;
int64 frame_id_;
IMPLEMENT_REFCOUNTING(CefFrameImpl);
DISALLOW_EVIL_CONSTRUCTORS(CefFrameImpl);
};
#endif // CEF_LIBCEF_RENDERER_FRAME_IMPL_H_

View File

@@ -0,0 +1,69 @@
/// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/renderer/render_message_filter.h"
#include "libcef/renderer/thread_util.h"
#include "libcef/common/cef_messages.h"
#include "base/bind.h"
#include "googleurl/src/gurl.h"
#include "googleurl/src/url_util.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
CefRenderMessageFilter::CefRenderMessageFilter()
: channel_(NULL) {
}
CefRenderMessageFilter::~CefRenderMessageFilter() {
}
void CefRenderMessageFilter::OnFilterAdded(IPC::Channel* channel) {
channel_ = channel;
}
void CefRenderMessageFilter::OnFilterRemoved() {
}
bool CefRenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CefRenderMessageFilter, message)
IPC_MESSAGE_HANDLER(CefProcessMsg_RegisterScheme, OnRegisterScheme)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void CefRenderMessageFilter::OnRegisterScheme(
const std::string& scheme_name,
bool is_standard,
bool is_local,
bool is_display_isolated) {
if (is_standard) {
// Make this registration as early as possible.
url_parse::Component scheme_comp(0, scheme_name.length());
if (!url_util::IsStandard(scheme_name.c_str(), scheme_comp))
url_util::AddStandardScheme(scheme_name.c_str());
}
CEF_POST_TASK_RT(
base::Bind(&CefRenderMessageFilter::RegisterSchemeOnRenderThread, this,
scheme_name, is_local, is_display_isolated));
}
void CefRenderMessageFilter::RegisterSchemeOnRenderThread(
const std::string& scheme_name,
bool is_local,
bool is_display_isolated) {
CEF_REQUIRE_RT();
if (is_local) {
WebKit::WebSecurityPolicy::registerURLSchemeAsLocal(
WebKit::WebString::fromUTF8(scheme_name));
}
if (is_display_isolated) {
WebKit::WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(
WebKit::WebString::fromUTF8(scheme_name));
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_RENDER_MESSAGE_FILTER_H_
#define CEF_LIBCEF_RENDERER_RENDER_MESSAGE_FILTER_H_
#include <string>
#include "ipc/ipc_channel_proxy.h"
// This class sends and receives control messages on the renderer process.
class CefRenderMessageFilter : public IPC::ChannelProxy::MessageFilter {
public:
CefRenderMessageFilter();
virtual ~CefRenderMessageFilter();
// IPC::ChannelProxy::MessageFilter implementation.
virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
virtual void OnFilterRemoved() OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
// Message handlers called on the IO thread.
void OnRegisterScheme(const std::string& scheme_name,
bool is_standard,
bool is_local,
bool is_display_isolated);
void RegisterSchemeOnRenderThread(const std::string& scheme_name,
bool is_local,
bool is_display_isolated);
IPC::Channel* channel_;
DISALLOW_COPY_AND_ASSIGN(CefRenderMessageFilter);
};
#endif // CEF_LIBCEF_RENDERER_RENDER_MESSAGE_FILTER_H_

View File

@@ -0,0 +1,86 @@
/// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/renderer/render_process_observer.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/content_client.h"
#include "base/bind.h"
#include "base/path_service.h"
#include "googleurl/src/gurl.h"
#include "googleurl/src/url_util.h"
#include "media/base/media.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
CefRenderProcessObserver::CefRenderProcessObserver() {
// Note that under Linux, the media library will normally already have
// been initialized by the Zygote before this instance became a Renderer.
FilePath media_path;
PathService::Get(base::DIR_MODULE, &media_path);
if (!media_path.empty())
media::InitializeMediaLibrary(media_path);
}
CefRenderProcessObserver::~CefRenderProcessObserver() {
}
bool CefRenderProcessObserver::OnControlMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CefRenderProcessObserver, message)
IPC_MESSAGE_HANDLER(CefProcessMsg_ModifyCrossOriginWhitelistEntry,
OnModifyCrossOriginWhitelistEntry)
IPC_MESSAGE_HANDLER(CefProcessMsg_ClearCrossOriginWhitelist,
OnClearCrossOriginWhitelist)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void CefRenderProcessObserver::WebKitInitialized() {
WebKit::WebRuntimeFeatures::enableMediaPlayer(
media::IsMediaLibraryInitialized());
// TODO(cef): Enable these once the implementation supports it.
WebKit::WebRuntimeFeatures::enableNotifications(false);
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
if (application.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
application->GetRenderProcessHandler();
if (handler.get())
handler->OnWebKitInitialized();
}
}
void CefRenderProcessObserver::OnModifyCrossOriginWhitelistEntry(
bool add,
const std::string& source_origin,
const std::string& target_protocol,
const std::string& target_domain,
bool allow_target_subdomains) {
GURL gurl = GURL(source_origin);
if (add) {
WebKit::WebSecurityPolicy::addOriginAccessWhitelistEntry(
gurl,
WebKit::WebString::fromUTF8(target_protocol),
WebKit::WebString::fromUTF8(target_domain),
allow_target_subdomains);
} else {
WebKit::WebSecurityPolicy::removeOriginAccessWhitelistEntry(
gurl,
WebKit::WebString::fromUTF8(target_protocol),
WebKit::WebString::fromUTF8(target_domain),
allow_target_subdomains);
}
}
void CefRenderProcessObserver::OnClearCrossOriginWhitelist() {
WebKit::WebSecurityPolicy::resetOriginAccessWhitelists();
}

View File

@@ -0,0 +1,36 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_RENDER_PROCESS_OBSERVER_H_
#define CEF_LIBCEF_RENDERER_RENDER_PROCESS_OBSERVER_H_
#include <string>
#include "base/memory/ref_counted.h"
#include "content/public/renderer/render_process_observer.h"
// This class sends and receives control messages on the renderer process.
class CefRenderProcessObserver : public content::RenderProcessObserver {
public:
CefRenderProcessObserver();
virtual ~CefRenderProcessObserver();
// RenderProcessObserver implementation.
virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void WebKitInitialized() OVERRIDE;
private:
// Message handlers called on the render thread.
void OnModifyCrossOriginWhitelistEntry(bool add,
const std::string& source_origin,
const std::string& target_protocol,
const std::string& target_domain,
bool allow_target_subdomains);
void OnClearCrossOriginWhitelist();
DISALLOW_COPY_AND_ASSIGN(CefRenderProcessObserver);
};
#endif // CEF_LIBCEF_RENDERER_RENDER_PROCESS_OBSERVER_H_

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_THREAD_UTIL_H_
#define CEF_LIBCEF_RENDERER_THREAD_UTIL_H_
#pragma once
#include "libcef/renderer/content_renderer_client.h"
#include "base/location.h"
#include "base/logging.h"
#include "content/public/renderer/render_thread.h"
#define CEF_CURRENTLY_ON_RT() (!!content::RenderThread::Get())
#define CEF_REQUIRE_RT() DCHECK(CEF_CURRENTLY_ON_RT())
#define CEF_REQUIRE_RT_RETURN(var) \
if (!CEF_CURRENTLY_ON_RT()) { \
NOTREACHED() << "called on invalid thread"; \
return var; \
}
#define CEF_REQUIRE_RT_RETURN_VOID() \
if (!CEF_CURRENTLY_ON_RT()) { \
NOTREACHED() << "called on invalid thread"; \
return; \
}
#define CEF_RENDER_LOOP() (CefContentRendererClient::Get()->render_loop())
#define CEF_POST_TASK_RT(task) \
CEF_RENDER_LOOP()->PostTask(FROM_HERE, task)
#define CEF_POST_DELAYED_TASK_RT(task, delay_ms) \
CEF_RENDER_LOOP()->PostDelayedTask(FROM_HERE, task, delay_ms)
// Use this template in conjuction with RefCountedThreadSafe when you want to
// ensure that an object is deleted on the render thread.
struct CefDeleteOnRenderThread {
template<typename T>
static void Destruct(const T* x) {
if (CEF_CURRENTLY_ON_RT()) {
delete x;
} else {
if (!CEF_RENDER_LOOP()->DeleteSoon(FROM_HERE, x)) {
#if defined(UNIT_TEST)
// Only logged under unit testing because leaks at shutdown
// are acceptable under normal circumstances.
LOG(ERROR) << "DeleteSoon failed on thread " << thread;
#endif // UNIT_TEST
}
}
}
};
#endif // CEF_LIBCEF_RENDERER_THREAD_UTIL_H_

1275
libcef/renderer/v8_impl.cc Normal file

File diff suppressed because it is too large Load Diff

187
libcef/renderer/v8_impl.h Normal file
View File

@@ -0,0 +1,187 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_V8_IMPL_H_
#define CEF_LIBCEF_RENDERER_V8_IMPL_H_
#pragma once
#include <vector>
#include "include/cef_v8.h"
#include "libcef/renderer/thread_util.h"
#include "v8/include/v8.h"
#include "base/memory/ref_counted.h"
class CefTrackNode;
namespace WebKit {
class WebFrame;
};
// Template for V8 Handle types. This class is used to ensure that V8 objects
// are only released on the UI thread.
template <class v8class>
class CefReleaseV8HandleOnUIThread
: public base::RefCountedThreadSafe<CefReleaseV8HandleOnUIThread<v8class>,
CefDeleteOnRenderThread> {
public:
typedef v8::Handle<v8class> handleType;
typedef v8::Persistent<v8class> persistentType;
typedef CefReleaseV8HandleOnUIThread<v8class> superType;
explicit CefReleaseV8HandleOnUIThread(handleType v) {
v8_handle_ = persistentType::New(v);
}
virtual ~CefReleaseV8HandleOnUIThread() {
}
handleType GetHandle() {
return v8_handle_;
}
persistentType v8_handle_;
};
// Special class for a v8::Context to ensure that it is deleted from the UI
// thread.
class CefV8ContextHandle : public CefReleaseV8HandleOnUIThread<v8::Context> {
public:
explicit CefV8ContextHandle(handleType context)
: superType(context) {
}
// Context handles are disposed rather than makeweak.
~CefV8ContextHandle() {
v8_handle_.Dispose();
v8_handle_.Clear();
}
};
class CefV8ContextImpl : public CefV8Context {
public:
explicit CefV8ContextImpl(v8::Handle<v8::Context> context);
virtual ~CefV8ContextImpl();
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual CefRefPtr<CefFrame> GetFrame() OVERRIDE;
virtual CefRefPtr<CefV8Value> GetGlobal() OVERRIDE;
virtual bool Enter() OVERRIDE;
virtual bool Exit() OVERRIDE;
virtual bool IsSame(CefRefPtr<CefV8Context> that) OVERRIDE;
virtual bool Eval(const CefString& code,
CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception) OVERRIDE;
v8::Local<v8::Context> GetContext();
WebKit::WebFrame* GetWebFrame();
protected:
scoped_refptr<CefV8ContextHandle> v8_context_;
#ifndef NDEBUG
// Used in debug builds to catch missing Exits in destructor.
int enter_count_;
#endif
IMPLEMENT_REFCOUNTING(CefV8ContextImpl);
};
// Special class for a v8::Value to ensure that it is deleted from the UI
// thread.
class CefV8ValueHandle: public CefReleaseV8HandleOnUIThread<v8::Value> {
public:
CefV8ValueHandle(handleType value, CefTrackNode* tracker)
: superType(value),
tracker_(tracker) {
}
// Destructor implementation is provided in v8_impl.cc.
~CefV8ValueHandle();
CefTrackNode* GetTracker() {
return tracker_;
}
private:
// For Object and Function types, we need to hold on to a reference to their
// internal data or function handler objects that are reference counted.
CefTrackNode* tracker_;
DISALLOW_COPY_AND_ASSIGN(CefV8ValueHandle);
};
class CefV8ValueImpl : public CefV8Value {
public:
CefV8ValueImpl(v8::Handle<v8::Value> value, CefTrackNode* tracker = NULL);
virtual ~CefV8ValueImpl();
virtual bool IsUndefined() OVERRIDE;
virtual bool IsNull() OVERRIDE;
virtual bool IsBool() OVERRIDE;
virtual bool IsInt() OVERRIDE;
virtual bool IsUInt() OVERRIDE;
virtual bool IsDouble() OVERRIDE;
virtual bool IsDate() OVERRIDE;
virtual bool IsString() OVERRIDE;
virtual bool IsObject() OVERRIDE;
virtual bool IsArray() OVERRIDE;
virtual bool IsFunction() OVERRIDE;
virtual bool IsSame(CefRefPtr<CefV8Value> value) OVERRIDE;
virtual bool GetBoolValue() OVERRIDE;
virtual int32 GetIntValue() OVERRIDE;
virtual uint32 GetUIntValue() OVERRIDE;
virtual double GetDoubleValue() OVERRIDE;
virtual CefTime GetDateValue() OVERRIDE;
virtual CefString GetStringValue() OVERRIDE;
virtual bool IsUserCreated() OVERRIDE;
virtual bool HasException() OVERRIDE;
virtual CefRefPtr<CefV8Exception> GetException() OVERRIDE;
virtual bool ClearException() OVERRIDE;
virtual bool WillRethrowExceptions() OVERRIDE;
virtual bool SetRethrowExceptions(bool rethrow) OVERRIDE;
virtual bool HasValue(const CefString& key) OVERRIDE;
virtual bool HasValue(int index) OVERRIDE;
virtual bool DeleteValue(const CefString& key) OVERRIDE;
virtual bool DeleteValue(int index) OVERRIDE;
virtual CefRefPtr<CefV8Value> GetValue(const CefString& key) OVERRIDE;
virtual CefRefPtr<CefV8Value> GetValue(int index) OVERRIDE;
virtual bool SetValue(const CefString& key, CefRefPtr<CefV8Value> value,
PropertyAttribute attribute) OVERRIDE;
virtual bool SetValue(int index, CefRefPtr<CefV8Value> value) OVERRIDE;
virtual bool SetValue(const CefString& key, AccessControl settings,
PropertyAttribute attribute) OVERRIDE;
virtual bool GetKeys(std::vector<CefString>& keys) OVERRIDE;
virtual bool SetUserData(CefRefPtr<CefBase> user_data) OVERRIDE;
virtual CefRefPtr<CefBase> GetUserData() OVERRIDE;
virtual int GetExternallyAllocatedMemory() OVERRIDE;
virtual int AdjustExternallyAllocatedMemory(int change_in_bytes) OVERRIDE;
virtual int GetArrayLength() OVERRIDE;
virtual CefString GetFunctionName() OVERRIDE;
virtual CefRefPtr<CefV8Handler> GetFunctionHandler() OVERRIDE;
virtual CefRefPtr<CefV8Value> ExecuteFunction(
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) OVERRIDE;
virtual CefRefPtr<CefV8Value> ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) OVERRIDE;
inline v8::Handle<v8::Value> GetHandle() {
DCHECK(v8_value_.get());
return v8_value_->GetHandle();
}
protected:
// Test for and record any exception.
bool HasCaught(v8::TryCatch& try_catch);
scoped_refptr<CefV8ValueHandle> v8_value_;
CefRefPtr<CefV8Exception> last_exception_;
bool rethrow_exceptions_;
IMPLEMENT_REFCOUNTING(CefV8ValueImpl);
DISALLOW_COPY_AND_ASSIGN(CefV8ValueImpl);
};
#endif // CEF_LIBCEF_RENDERER_V8_IMPL_H_

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/renderer/webkit_glue.h"
#include "base/compiler_specific.h"
#include "third_party/WebKit/Source/WebCore/config.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "Page.h"
#include "third_party/WebKit/Source/WebKit/chromium/src/WebFrameImpl.h"
#include "third_party/WebKit/Source/WebKit/chromium/src/WebViewImpl.h"
MSVC_POP_WARNING();
#undef LOG
namespace webkit_glue {
bool CanGoBackOrForward(WebKit::WebView* view, int distance) {
if (!view)
return false;
WebKit::WebViewImpl* impl = reinterpret_cast<WebKit::WebViewImpl*>(view);
return impl->page()->canGoBackOrForward(distance);
}
void GoBackOrForward(WebKit::WebView* view, int distance) {
if (!view)
return;
WebKit::WebViewImpl* impl = reinterpret_cast<WebKit::WebViewImpl*>(view);
impl->page()->goBackOrForward(distance);
}
v8::Handle<v8::Context> GetV8Context(WebKit::WebFrame* frame) {
WebKit::WebFrameImpl* impl = static_cast<WebKit::WebFrameImpl*>(frame);
WebCore::Frame* core_frame = impl->frame();
return WebCore::V8Proxy::context(core_frame);
}
} // webkit_glue

View File

@@ -0,0 +1,27 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_RENDERER_WEBKIT_GLUE_H_
#define CEF_LIBCEF_RENDERER_WEBKIT_GLUE_H_
#include <string>
#include "v8/include/v8.h"
namespace WebKit {
class WebFrame;
class WebView;
}
namespace webkit_glue {
bool CanGoBackOrForward(WebKit::WebView* view, int distance);
void GoBackOrForward(WebKit::WebView* view, int distance);
// Retrieve the V8 context associated with the frame.
v8::Handle<v8::Context> GetV8Context(WebKit::WebFrame* frame);
} // webkit_glue
#endif // CEF_LIBCEF_RENDERER_WEBKIT_GLUE_H_