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,11 @@
// 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_BROWSER_APPLICATION_MAC_H_
#define CEF_LIBCEF_BROWSER_APPLICATION_MAC_H_
// Create the CefCrApplication instance used by secondary processes.
void CefCrApplicationCreate();
#endif // CEF_LIBCEF_BROWSER_APPLICATION_MAC_H_

View File

@@ -0,0 +1,46 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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/browser/application_mac.h"
#include "base/message_pump_mac.h"
#include "base/mac/scoped_sending_event.h"
@interface CefCrApplication : NSApplication<CrAppProtocol,
CrAppControlProtocol> {
@private
BOOL handlingSendEvent_;
}
// CrAppProtocol:
- (BOOL)isHandlingSendEvent;
// CrAppControlProtocol:
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
@end
@implementation CefCrApplication
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}
- (void)sendEvent:(NSEvent*)event {
BOOL wasHandlingSendEvent = handlingSendEvent_;
handlingSendEvent_ = YES;
[super sendEvent:event];
handlingSendEvent_ = wasHandlingSendEvent;
}
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
handlingSendEvent_ = handlingSendEvent;
}
@end
void CefCrApplicationCreate() {
[CefCrApplication sharedApplication];
}

View File

@@ -0,0 +1,300 @@
// 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/browser/browser_context.h"
#include <map>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_main.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/resource_context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "base/bind.h"
#include "base/environment.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/threading/thread.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/geolocation_permission_context.h"
#include "content/public/browser/speech_recognition_preferences.h"
#if defined(OS_WIN)
#include "base/base_paths_win.h"
#elif defined(OS_LINUX)
#include "base/nix/xdg_util.h"
#endif
using content::BrowserThread;
namespace {
#if defined(OS_LINUX)
const char kDotConfigDir[] = ".config";
const char kXdgConfigHomeEnvVar[] = "XDG_CONFIG_HOME";
#endif
class CefGeolocationPermissionContext
: public content::GeolocationPermissionContext {
public:
// CefGeolocationCallback implementation.
class CallbackImpl : public CefGeolocationCallback {
public:
typedef base::Callback<void(bool)> // NOLINT(readability/function)
CallbackType;
explicit CallbackImpl(
CefGeolocationPermissionContext* context,
int bridge_id,
const CallbackType& callback)
: context_(context),
bridge_id_(bridge_id),
callback_(callback) {}
virtual void Continue(bool allow) OVERRIDE {
if (CEF_CURRENTLY_ON_IOT()) {
if (!callback_.is_null()) {
// Callback must be executed on the UI thread.
CEF_POST_TASK(CEF_UIT,
base::Bind(&CallbackImpl::Run, callback_, allow));
context_->RemoveCallback(bridge_id_);
}
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CallbackImpl::Continue, this, allow));
}
}
void Disconnect() {
callback_.Reset();
context_ = NULL;
}
private:
static void Run(const CallbackType& callback, bool allow) {
CEF_REQUIRE_UIT();
callback.Run(allow);
}
CefGeolocationPermissionContext* context_;
int bridge_id_;
CallbackType callback_;
IMPLEMENT_REFCOUNTING(CallbackImpl);
};
CefGeolocationPermissionContext() {}
virtual void RequestGeolocationPermission(
int render_process_id,
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
base::Callback<void(bool)> callback) // NOLINT(readability/function)
OVERRIDE {
CEF_REQUIRE_IOT();
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserByRoutingID(render_process_id,
render_view_id);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefGeolocationHandler> handler =
client->GetGeolocationHandler();
if (handler.get()) {
CefRefPtr<CallbackImpl> callbackPtr(
new CallbackImpl(this, bridge_id, callback));
// Add the callback reference to the map.
callback_map_.insert(std::make_pair(bridge_id, callbackPtr));
// Notify the handler.
handler->OnRequestGeolocationPermission(browser.get(),
requesting_frame.spec(), bridge_id, callbackPtr.get());
return;
}
}
}
// Disallow geolocation access by default.
callback.Run(false);
}
virtual void CancelGeolocationPermissionRequest(
int render_process_id,
int render_view_id,
int bridge_id,
const GURL& requesting_frame) OVERRIDE {
RemoveCallback(bridge_id);
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserByRoutingID(render_process_id,
render_view_id);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefGeolocationHandler> handler =
client->GetGeolocationHandler();
if (handler.get()) {
// Notify the handler.
handler->OnCancelGeolocationPermission(browser.get(),
requesting_frame.spec(), bridge_id);
}
}
}
}
void RemoveCallback(int bridge_id) {
CEF_REQUIRE_IOT();
// Disconnect the callback and remove the reference from the map.
CallbackMap::iterator it = callback_map_.find(bridge_id);
if (it != callback_map_.end()) {
it->second->Disconnect();
callback_map_.erase(it);
}
}
private:
// Map of bridge ids to callback references.
typedef std::map<int, CefRefPtr<CallbackImpl> > CallbackMap;
CallbackMap callback_map_;
DISALLOW_COPY_AND_ASSIGN(CefGeolocationPermissionContext);
};
class CefSpeechRecognitionPreferences
: public content::SpeechRecognitionPreferences {
public:
CefSpeechRecognitionPreferences() {
}
// Overridden from SpeechRecognitionPreferences:
virtual bool FilterProfanities() const OVERRIDE {
return false;
}
virtual void SetFilterProfanities(bool filter_profanities) OVERRIDE {
}
private:
DISALLOW_COPY_AND_ASSIGN(CefSpeechRecognitionPreferences);
};
} // namespace
CefBrowserContext::CefBrowserContext(
CefBrowserMainParts* main_parts)
: main_parts_(main_parts) {
// Initialize the request context getter.
url_request_getter_ = new CefURLRequestContextGetter(
GetPath(),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE));
}
CefBrowserContext::~CefBrowserContext() {
if (resource_context_.get()) {
BrowserThread::DeleteSoon(
BrowserThread::IO, FROM_HERE, resource_context_.release());
}
}
FilePath CefBrowserContext::GetPath() {
if (!path_.empty())
return path_;
#if defined(OS_WIN)
CHECK(PathService::Get(base::DIR_LOCAL_APP_DATA, &path_));
path_ = path_.Append(std::wstring(L"cef_data"));
#elif defined(OS_LINUX)
scoped_ptr<base::Environment> env(base::Environment::Create());
FilePath config_dir(base::nix::GetXDGDirectory(env.get(),
kXdgConfigHomeEnvVar,
kDotConfigDir));
path_ = config_dir.Append("cef_data");
#elif defined(OS_MACOSX)
CHECK(PathService::Get(base::DIR_APP_DATA, &path_));
path_ = path_.Append("cef_data");
#else
NOTIMPLEMENTED();
#endif
if (!file_util::PathExists(path_))
file_util::CreateDirectory(path_);
return path_;
}
bool CefBrowserContext::IsOffTheRecord() const {
return false;
}
content::DownloadManager* CefBrowserContext::GetDownloadManager() {
if (!download_manager_.get()) {
download_manager_delegate_ = new CefDownloadManagerDelegate();
download_manager_ = new DownloadManagerImpl(download_manager_delegate_,
NULL);
download_manager_delegate_->SetDownloadManager(download_manager_.get());
download_manager_->Init(this);
}
return download_manager_.get();
}
net::URLRequestContextGetter* CefBrowserContext::GetRequestContext() {
return url_request_getter_;
}
net::URLRequestContextGetter*
CefBrowserContext::GetRequestContextForRenderProcess(
int renderer_child_id) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserByChildID(renderer_child_id);
if (browser.get())
return browser->GetRequestContext();
return GetRequestContext();
}
net::URLRequestContextGetter*
CefBrowserContext::GetRequestContextForMedia() {
return GetRequestContext();
}
content::ResourceContext* CefBrowserContext::GetResourceContext() {
if (!resource_context_.get()) {
resource_context_.reset(new CefResourceContext(
static_cast<CefURLRequestContextGetter*>(GetRequestContext())));
}
return resource_context_.get();
}
content::GeolocationPermissionContext*
CefBrowserContext::GetGeolocationPermissionContext() {
if (!geolocation_permission_context_) {
geolocation_permission_context_ =
new CefGeolocationPermissionContext();
}
return geolocation_permission_context_;
}
content::SpeechRecognitionPreferences*
CefBrowserContext::GetSpeechRecognitionPreferences() {
if (!speech_recognition_preferences_.get())
speech_recognition_preferences_ = new CefSpeechRecognitionPreferences();
return speech_recognition_preferences_.get();
}
bool CefBrowserContext::DidLastSessionExitCleanly() {
return true;
}
quota::SpecialStoragePolicy* CefBrowserContext::GetSpecialStoragePolicy() {
return NULL;
}

View File

@@ -0,0 +1,64 @@
// 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_BROWSER_BROWSER_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_H_
#pragma once
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_context.h"
class DownloadManager;
namespace content {
class DownloadManagerDelegate;
class ResourceContext;
class SpeechRecognitionPreferences;
}
class CefBrowserMainParts;
class CefDownloadManagerDelegate;
class CefBrowserContext : public content::BrowserContext {
public:
explicit CefBrowserContext(CefBrowserMainParts* main_parts);
virtual ~CefBrowserContext();
// BrowserContext methods.
virtual FilePath GetPath() OVERRIDE;
virtual bool IsOffTheRecord() const OVERRIDE;
virtual content::DownloadManager* GetDownloadManager() OVERRIDE;
virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
int renderer_child_id) OVERRIDE;
virtual net::URLRequestContextGetter* GetRequestContextForMedia() OVERRIDE;
virtual content::ResourceContext* GetResourceContext() OVERRIDE;
virtual content::GeolocationPermissionContext*
GetGeolocationPermissionContext() OVERRIDE;
virtual content::SpeechRecognitionPreferences*
GetSpeechRecognitionPreferences() OVERRIDE;
virtual bool DidLastSessionExitCleanly() OVERRIDE;
virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
private:
FilePath path_;
scoped_ptr<content::ResourceContext> resource_context_;
scoped_refptr<CefDownloadManagerDelegate> download_manager_delegate_;
scoped_refptr<content::DownloadManager> download_manager_;
scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
scoped_refptr<content::GeolocationPermissionContext>
geolocation_permission_context_;
scoped_refptr<content::SpeechRecognitionPreferences>
speech_recognition_preferences_;
CefBrowserMainParts* main_parts_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserContext);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,356 @@
// 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_BROWSER_BROWSER_HOST_IMPL_H_
#define CEF_LIBCEF_BROWSER_BROWSER_HOST_IMPL_H_
#pragma once
#include <map>
#include <queue>
#include <string>
#include <vector>
#include "include/cef_browser.h"
#include "include/cef_client.h"
#include "include/cef_frame.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/url_request_context_getter_proxy.h"
#include "libcef/common/response_manager.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "base/synchronization/lock.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
struct Cef_Request_Params;
struct Cef_Response_Params;
struct CefNavigateParams;
class SiteInstance;
// Implementation of CefBrowser.
//
// WebContentsDelegate: Interface for handling TabContents delegations. There is
// a one-to-one relationship between CefBrowserHostImpl and TabContents
// instances.
//
// WebContentsObserver: Interface for observing TabContents notifications and
// IPC messages. There is a one-to-one relationship between TabContents and
// RenderViewHost instances. IPC messages received by the RenderViewHost will be
// forwarded to this WebContentsObserver implementation via TabContents. IPC
// messages sent using CefBrowserHostImpl::Send() will be forwarded to the
// RenderViewHost (after posting to the UI thread if necessary). Use
// WebContentsObserver::routing_id() when sending IPC messages.
//
// NotificationObserver: Interface for observing post-processed notifications.
class CefBrowserHostImpl : public CefBrowserHost,
public CefBrowser,
public content::WebContentsDelegate,
public content::WebContentsObserver,
public content::NotificationObserver {
public:
// Used for handling the response to command messages.
class CommandResponseHandler : public virtual CefBase {
public:
virtual void OnResponse(const std::string& response) =0;
};
virtual ~CefBrowserHostImpl() {}
// Create a new CefBrowserHostImpl instance.
static CefRefPtr<CefBrowserHostImpl> Create(
const CefWindowInfo& window_info,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
TabContents* tab_contents,
CefWindowHandle opener);
// Returns the browser associated with the specified RenderViewHost.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForHost(
const content::RenderViewHost* host);
// Returns the browser associated with the specified WebContents.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForContents(
content::WebContents* contents);
// Returns the browser associated with the specified URLRequest.
static CefRefPtr<CefBrowserHostImpl> GetBrowserForRequest(
net::URLRequest* request);
// Returns the browser associated with the specified routing IDs.
static CefRefPtr<CefBrowserHostImpl> GetBrowserByRoutingID(
int render_process_id, int render_view_id);
// Returns the browser associated with the specified child process ID.
static CefRefPtr<CefBrowserHostImpl> GetBrowserByChildID(
int render_process_id);
// CefBrowserHost methods.
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual void CloseBrowser() OVERRIDE;
virtual void ParentWindowWillClose() OVERRIDE;
virtual void SetFocus(bool enable) OVERRIDE;
virtual CefWindowHandle GetWindowHandle() OVERRIDE;
virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE;
virtual CefRefPtr<CefClient> GetClient() OVERRIDE;
// 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;
// Set the unique identifier for this browser.
void SetUniqueId(int unique_id);
// Destroy the browser members. This method should only be called after the
// native browser window is not longer processing messages.
void DestroyBrowser();
// Returns the native view for the TabContents.
gfx::NativeView GetContentView() const;
// Returns a pointer to the TabContents.
TabContents* GetTabContents() const;
// Returns the browser-specific request context.
net::URLRequestContextGetter* GetRequestContext();
// Returns the frame associated with the specified URLRequest.
CefRefPtr<CefFrame> GetFrameForRequest(net::URLRequest* request);
// Navigate as specified by the |params| argument.
void Navigate(const CefNavigateParams& params);
// Load the specified request.
void LoadRequest(int64 frame_id, CefRefPtr<CefRequest> request);
// Load the specified URL.
void LoadURL(int64 frame_id, const std::string& url);
// Load the specified string.
void LoadString(int64 frame_id, const CefString& string,
const CefString& url);
// Send a command to the renderer for execution.
void SendCommand(int64 frame_id, const CefString& command,
CefRefPtr<CefResponseManager::Handler> responseHandler);
// Send code to the renderer for execution.
void SendCode(int64 frame_id, bool is_javascript, const CefString& code,
const CefString& script_url, int script_start_line,
CefRefPtr<CefResponseManager::Handler> responseHandler);
// Open the specified text in the default text editor.
bool ViewText(const std::string& text);
// Thread safe accessors.
const CefBrowserSettings& settings() const { return settings_; }
CefRefPtr<CefClient> client() const { return client_; }
int render_process_id() const { return render_process_id_; }
int render_view_id() const { return render_view_id_; }
int unique_id() const { return unique_id_; }
// Returns the URL that is currently loading (or loaded) in the main frame.
GURL GetLoadingURL();
#if defined(OS_WIN)
static void RegisterWindowClass();
#endif
private:
// content::WebContentsDelegate methods.
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE;
virtual void LoadingStateChanged(content::WebContents* source) OVERRIDE;
virtual bool ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
WindowContainerType window_container_type,
const string16& frame_name) OVERRIDE;
virtual void WebContentsCreated(content::WebContents* source_contents,
int64 source_frame_id,
const GURL& target_url,
content::WebContents* new_contents) OVERRIDE;
virtual void DidNavigateMainFramePostCommit(
content::WebContents* tab) OVERRIDE;
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
OVERRIDE;
virtual void RunFileChooser(
content::WebContents* tab,
const content::FileChooserParams& params) OVERRIDE;
virtual void UpdatePreferredSize(content::WebContents* source,
const gfx::Size& pref_size) OVERRIDE;
// content::WebContentsObserver methods.
virtual void RenderViewReady() OVERRIDE;
virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
bool is_main_frame,
const GURL& url,
content::PageTransition transition_type) OVERRIDE;
virtual void DidFailProvisionalLoad(
int64 frame_id,
bool is_main_frame,
const GURL& validated_url,
int error_code,
const string16& error_description) OVERRIDE;
virtual void DocumentAvailableInMainFrame() OVERRIDE;
virtual void DidFinishLoad(int64 frame_id,
const GURL& validated_url,
bool is_main_frame) OVERRIDE;
virtual void DidFailLoad(int64 frame_id,
const GURL& validated_url,
bool is_main_frame,
int error_code,
const string16& error_description) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// Override to provide a thread safe implementation.
virtual bool Send(IPC::Message* message) OVERRIDE;
// content::WebContentsObserver::OnMessageReceived() message handlers.
void OnFrameIdentified(int64 frame_id, int64 parent_frame_id, string16 name);
void OnLoadingURLChange(const GURL& pending_url);
void OnRequest(const Cef_Request_Params& params);
void OnResponse(const Cef_Response_Params& params);
void OnResponseAck(int request_id);
// content::NotificationObserver methods.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
CefBrowserHostImpl(const CefWindowInfo& window_info,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
TabContents* tab_contents,
CefWindowHandle opener);
// Updates and returns an existing frame or creates a new frame. Pass
// CefFrameHostImpl::kUnspecifiedFrameId for |parent_frame_id| if unknown.
CefRefPtr<CefFrame> GetOrCreateFrame(int64 frame_id,
int64 parent_frame_id,
bool is_main_frame,
string16 frame_name,
const GURL& frame_url);
// Remove the reference to the frame and mark it as detached.
void DetachFrame(int64 frame_id);
// Remove the references to all frames and mark them as detached.
void DetachAllFrames();
// Set the frame that currently has focus.
void SetFocusedFrame(int64 frame_id);
#if defined(OS_WIN)
static LPCTSTR GetWndClass();
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
#endif
// Create the window.
bool PlatformCreateWindow();
// Sends a message via the OS to close the native browser window.
// DestroyBrowser will be called after the native window has closed.
void PlatformCloseWindow();
// Resize the window to the given dimensions.
void PlatformSizeTo(int width, int height);
// Return the handle for this window.
CefWindowHandle PlatformGetWindowHandle();
// Open the specified text in the default text editor.
bool PlatformViewText(const std::string& text);
void OnAddressChange(CefRefPtr<CefFrame> frame,
const GURL& url);
void OnLoadStart(CefRefPtr<CefFrame> frame,
const GURL& url,
content::PageTransition transition_type);
void OnLoadError(CefRefPtr<CefFrame> frame,
const GURL& url,
int error_code,
const string16& error_description);
void OnLoadEnd(CefRefPtr<CefFrame> frame,
const GURL& url);
CefWindowInfo window_info_;
CefBrowserSettings settings_;
CefRefPtr<CefClient> client_;
scoped_ptr<TabContents> tab_contents_;
CefWindowHandle opener_;
// Unique ids used for routing communication to/from the renderer. We keep a
// copy of them as member variables so that we can locate matching browsers in
// a thread safe manner.
int render_process_id_;
int render_view_id_;
// Unique id for the browser.
int unique_id_;
// True if the browser has received the page title for the current load.
bool received_page_title_;
// Used when creating a new popup window.
CefWindowInfo pending_window_info_;
CefBrowserSettings pending_settings_;
CefRefPtr<CefClient> pending_client_;
CefString pending_url_;
// Volatile state information. All access must be protected by the state lock.
base::Lock state_lock_;
bool is_loading_;
bool can_go_back_;
bool can_go_forward_;
bool has_document_;
GURL loading_url_;
// Messages we queue while waiting for the RenderView to be ready. We queue
// them here instead of in the RenderProcessHost to ensure that they're sent
// after the CefRenderViewObserver has been created on the renderer side.
std::queue<IPC::Message*> queued_messages_;
bool queue_messages_;
// Map of unique frame ids to CefFrameHostImpl references.
typedef std::map<int64, CefRefPtr<CefFrameHostImpl> > FrameMap;
FrameMap frames_;
// The unique frame id currently identified as the main frame.
int64 main_frame_id_;
// The unique frame id currently identified as the focused frame.
int64 focused_frame_id_;
// Used when no other frame exists. Provides limited functionality.
CefRefPtr<CefFrameHostImpl> placeholder_frame_;
// Manages response registrations.
CefResponseManager response_manager_;
// Used for managing notification subscriptions.
scoped_ptr<content::NotificationRegistrar> registrar_;
// Used for proxying cookie requests.
scoped_refptr<CefURLRequestContextGetterProxy> request_context_proxy_;
IMPLEMENT_REFCOUNTING(CefBrowserHostImpl);
DISALLOW_EVIL_CONSTRUCTORS(CefBrowserHostImpl);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_HOST_IMPL_H_

View File

@@ -0,0 +1,113 @@
// 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/browser/browser_host_impl.h"
#include <gtk/gtk.h>
#include "libcef/browser/thread_util.h"
#include "base/bind.h"
#include "content/public/browser/web_contents_view.h"
namespace {
void DestroyBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
browser->DestroyBrowser();
browser->Release();
}
void window_destroyed(GtkWidget* widget, CefBrowserHostImpl* browser) {
// Destroy the browser host after window destruction is complete.
CEF_POST_TASK(CEF_UIT, base::Bind(DestroyBrowser, browser));
}
} // namespace
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
CEF_REQUIRE_UIT();
char buff[] = "/tmp/CEFSourceXXXXXX";
int fd = mkstemp(buff);
if (fd == -1)
return false;
FILE* srcOutput = fdopen(fd, "w+");
if (!srcOutput)
return false;
if (fputs(text.c_str(), srcOutput) < 0) {
fclose(srcOutput);
return false;
}
fclose(srcOutput);
std::string newName(buff);
newName.append(".txt");
if (rename(buff, newName.c_str()) != 0)
return false;
std::string openCommand("xdg-open ");
openCommand += newName;
if (system(openCommand.c_str()) != 0)
return false;
return true;
}
bool CefBrowserHostImpl::PlatformCreateWindow() {
GtkWidget* window;
GtkWidget* parentView = window_info_.parent_widget;
if (parentView == NULL) {
// Create a new window.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
parentView = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), parentView);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show_all(GTK_WIDGET(window));
window_info_.parent_widget = parentView;
}
// Add a reference that will be released in the destroy handler.
AddRef();
// Parent the TabContents to the browser window.
window_info_.widget = tab_contents_->GetView()->GetNativeView();
gtk_container_add(GTK_CONTAINER(window_info_.parent_widget),
window_info_.widget);
g_signal_connect(G_OBJECT(window_info_.widget), "destroy",
G_CALLBACK(window_destroyed), this);
return true;
}
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_info_.widget != NULL) {
GtkWidget* window =
gtk_widget_get_toplevel(GTK_WIDGET(window_info_.widget));
gtk_widget_destroy(window);
}
}
void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
if (window_info_.widget != NULL) {
GtkWidget* window =
gtk_widget_get_toplevel(GTK_WIDGET(window_info_.widget));
gtk_widget_set_size_request(window, width, height);
}
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.widget;
}

View File

@@ -0,0 +1,162 @@
// 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/browser/browser_host_impl.h"
#import <Cocoa/Cocoa.h>
#include "content/public/browser/web_contents_view.h"
#include "ui/gfx/rect.h"
// Wrapper NSView for the native view. Necessary to destroy the browser when
// the view is deleted.
@interface CefBrowserHostView : NSView {
@private
CefBrowserHostImpl* browser_; // weak
}
@property (nonatomic, assign) CefBrowserHostImpl* browser;
@end
@implementation CefBrowserHostView
@synthesize browser = browser_;
- (void) dealloc {
if (browser_) {
browser_->DestroyBrowser();
browser_->Release();
}
[super dealloc];
}
@end
// Common base class for CEF browser windows. Contains methods relating to hole
// punching required in order to display OpenGL underlay windows.
@interface CefBrowserWindow : NSWindow {
@private
int underlaySurfaceCount_;
}
// Informs the window that an underlay surface has been added/removed. The
// window is non-opaque while underlay surfaces are present.
- (void)underlaySurfaceAdded;
- (void)underlaySurfaceRemoved;
@end
@implementation CefBrowserWindow
- (void)underlaySurfaceAdded {
DCHECK_GE(underlaySurfaceCount_, 0);
++underlaySurfaceCount_;
// We're having the OpenGL surface render under the window, so the window
// needs to be not opaque.
if (underlaySurfaceCount_ == 1)
[self setOpaque:NO];
}
- (void)underlaySurfaceRemoved {
--underlaySurfaceCount_;
DCHECK_GE(underlaySurfaceCount_, 0);
if (underlaySurfaceCount_ == 0)
[self setOpaque:YES];
}
@end
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
NOTIMPLEMENTED();
return false;
}
bool CefBrowserHostImpl::PlatformCreateWindow() {
NSWindow* newWnd = nil;
NSView* parentView = window_info_.parent_view;
NSRect contentRect = {{window_info_.x, window_info_.y},
{window_info_.width, window_info_.height}};
if (parentView == nil) {
// Create a new window.
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
NSRect window_rect = {{window_info_.x,
screen_rect.size.height - window_info_.y},
{window_info_.width, window_info_.height}};
if (window_rect.size.width == 0)
window_rect.size.width = 750;
if (window_rect.size.height == 0)
window_rect.size.height = 750;
contentRect.origin.x = 0;
contentRect.origin.y = 0;
contentRect.size.width = window_rect.size.width;
contentRect.size.height = window_rect.size.height;
newWnd = [[CefBrowserWindow alloc]
initWithContentRect:window_rect
styleMask:(NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask |
NSResizableWindowMask |
NSUnifiedTitleAndToolbarWindowMask )
backing:NSBackingStoreBuffered
defer:NO];
parentView = [newWnd contentView];
window_info_.parent_view = parentView;
}
// Add a reference that will be released in the dealloc handler.
AddRef();
// Create the browser view.
CefBrowserHostView* browser_view =
[[CefBrowserHostView alloc] initWithFrame:contentRect];
browser_view.browser = this;
[parentView addSubview:browser_view];
[browser_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[browser_view setNeedsDisplay:YES];
[browser_view release];
// Parent the TabContents to the browser view.
const NSRect bounds = [browser_view bounds];
NSView* native_view = tab_contents_->GetView()->GetNativeView();
[browser_view addSubview:native_view];
[native_view setFrame:bounds];
[native_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[native_view setNeedsDisplay:YES];
window_info_.view = browser_view;
if (newWnd != nil && !window_info_.hidden) {
// Show the window.
[newWnd makeKeyAndOrderFront: nil];
}
return true;
}
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_info_.view != nil) {
[[window_info_.view window] performSelector:@selector(performClose:)
withObject:nil
afterDelay:0];
}
}
void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
// Not needed; subviews are bound.
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.view;
}

View File

@@ -0,0 +1,256 @@
// 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/browser/browser_host_impl.h"
#include <dwmapi.h>
#include <shellapi.h>
#include <shlwapi.h>
#include <wininet.h>
#include <winspool.h>
#include "libcef/browser/thread_util.h"
#include "base/win/windows_version.h"
#include "content/public/browser/web_contents_view.h"
#include "ui/base/win/hwnd_util.h"
#pragma comment(lib, "dwmapi.lib")
namespace {
bool IsAeroGlassEnabled() {
if (base::win::GetVersion() < base::win::VERSION_VISTA)
return false;
BOOL enabled = FALSE;
return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled;
}
void SetAeroGlass(HWND hWnd) {
if (!IsAeroGlassEnabled())
return;
// Make the whole window transparent.
MARGINS mgMarInset = { -1, -1, -1, -1 };
DwmExtendFrameIntoClientArea(hWnd, &mgMarInset);
}
void WriteTextToFile(const std::string& data, const std::wstring& file_path) {
FILE* fp;
errno_t err = _wfopen_s(&fp, file_path.c_str(), L"wt");
if (err)
return;
fwrite(data.c_str(), 1, data.size(), fp);
fclose(fp);
}
} // namespace
// static
void CefBrowserHostImpl::RegisterWindowClass() {
// Register the window class
WNDCLASSEX wcex = {
/* cbSize = */ sizeof(WNDCLASSEX),
/* style = */ CS_HREDRAW | CS_VREDRAW,
/* lpfnWndProc = */ CefBrowserHostImpl::WndProc,
/* cbClsExtra = */ 0,
/* cbWndExtra = */ 0,
/* hInstance = */ ::GetModuleHandle(NULL),
/* hIcon = */ NULL,
/* hCursor = */ LoadCursor(NULL, IDC_ARROW),
/* hbrBackground = */ 0,
/* lpszMenuName = */ NULL,
/* lpszClassName = */ CefBrowserHostImpl::GetWndClass(),
/* hIconSm = */ NULL,
};
RegisterClassEx(&wcex);
}
// static
LPCTSTR CefBrowserHostImpl::GetWndClass() {
return L"CefBrowserWindow";
}
// static
LRESULT CALLBACK CefBrowserHostImpl::WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam) {
CefBrowserHostImpl* browser =
static_cast<CefBrowserHostImpl*>(ui::GetWindowUserData(hwnd));
switch (message) {
case WM_CLOSE:
if (browser) {
bool handled(false);
if (browser->client_.get()) {
CefRefPtr<CefLifeSpanHandler> handler =
browser->client_->GetLifeSpanHandler();
if (handler.get()) {
// Give the client a chance to handle this one.
handled = handler->DoClose(browser);
}
}
if (handled)
return 0;
// We are our own parent in this case.
browser->ParentWindowWillClose();
}
break;
case WM_DESTROY:
if (browser) {
// Clear the user data pointer.
ui::SetWindowUserData(hwnd, NULL);
// Destroy the browser.
browser->DestroyBrowser();
// Release the reference added in PlatformCreateWindow(). There should be
// no other references to the browser.
DCHECK_EQ(browser->GetRefCt(), 1);
browser->Release();
}
return 0;
case WM_SIZE:
if (browser) {
// resize the web view window to the full size of the browser window
RECT rc;
GetClientRect(hwnd, &rc);
MoveWindow(browser->GetContentView(), 0, 0, rc.right, rc.bottom,
TRUE);
}
return 0;
case WM_SETFOCUS:
if (browser) {
TabContents* tab_contents = browser->GetTabContents();
if (tab_contents)
tab_contents->Focus();
}
return 0;
case WM_ERASEBKGND:
return 0;
case WM_DWMCOMPOSITIONCHANGED:
// Message sent to top-level windows when composition has been enabled or
// disabled.
if (browser && browser->window_info_.transparent_painting)
SetAeroGlass(hwnd);
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
bool CefBrowserHostImpl::PlatformCreateWindow() {
std::wstring windowName(CefString(&window_info_.window_name));
// Create the new browser window.
window_info_.window = CreateWindowEx(window_info_.ex_style,
GetWndClass(), windowName.c_str(), window_info_.style,
window_info_.x, window_info_.y, window_info_.width,
window_info_.height, window_info_.parent_window, window_info_.menu,
::GetModuleHandle(NULL), NULL);
// It's possible for CreateWindowEx to fail if the parent window was
// destroyed between the call to CreateBrowser and the above one.
DCHECK(window_info_.window != NULL);
if (!window_info_.window)
return false;
if (window_info_.transparent_painting &&
!(window_info_.style & WS_CHILD)) {
// Transparent top-level windows will be given "sheet of glass" effect.
SetAeroGlass(window_info_.window);
}
// Set window user data to this object for future reference from the window
// procedure.
ui::SetWindowUserData(window_info_.window, this);
// Add a reference that will be released in the WM_DESTROY handler.
AddRef();
// Parent the TabContents to the browser window.
SetParent(tab_contents_->GetView()->GetNativeView(), window_info_.window);
// Size the web view window to the browser window.
RECT cr;
GetClientRect(window_info_.window, &cr);
// Respect the WS_VISIBLE window style when setting the window's position.
UINT flags = SWP_NOZORDER | SWP_SHOWWINDOW;
if (!(window_info_.style & WS_VISIBLE))
flags |= SWP_NOACTIVATE;
SetWindowPos(GetContentView(), NULL, cr.left, cr.top, cr.right,
cr.bottom, flags);
return true;
}
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_info_.window != NULL)
PostMessage(window_info_.window, WM_CLOSE, 0, 0);
}
void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
RECT rect = {0, 0, width, height};
DWORD style = GetWindowLong(window_info_.window, GWL_STYLE);
DWORD ex_style = GetWindowLong(window_info_.window, GWL_EXSTYLE);
bool has_menu = !(style & WS_CHILD) && (GetMenu(window_info_.window) != NULL);
// The size value is for the client area. Calculate the whole window size
// based on the current style.
AdjustWindowRectEx(&rect, style, has_menu, ex_style);
// Size the window.
SetWindowPos(window_info_.window, NULL, 0, 0, rect.right,
rect.bottom, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window;
}
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
CEF_REQUIRE_UIT();
DWORD dwRetVal;
DWORD dwBufSize = 512;
TCHAR lpPathBuffer[512];
UINT uRetVal;
TCHAR szTempName[512];
dwRetVal = GetTempPath(dwBufSize, // length of the buffer
lpPathBuffer); // buffer for path
if (dwRetVal > dwBufSize || (dwRetVal == 0))
return false;
// Create a temporary file.
uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
TEXT("src"), // temp file name prefix
0, // create unique name
szTempName); // buffer for name
if (uRetVal == 0)
return false;
size_t len = wcslen(szTempName);
wcscpy(szTempName + len - 3, L"txt");
WriteTextToFile(text, szTempName);
HWND frameWnd = GetAncestor(PlatformGetWindowHandle(), GA_ROOT);
int errorCode = reinterpret_cast<int>(ShellExecute(frameWnd, L"open",
szTempName, NULL, NULL, SW_SHOWNORMAL));
if (errorCode <= 32)
return false;
return true;
}

View File

@@ -0,0 +1,97 @@
// 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/browser/browser_main.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/devtools_delegate.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/download/download_file_manager.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/plugin_service_impl.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_module.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/resource/resource_bundle.h"
namespace {
base::StringPiece ResourceProvider(int resource_id) {
return content::GetContentClient()->GetDataResource(resource_id);
}
}
CefBrowserMainParts::CefBrowserMainParts(
const content::MainFunctionParams& parameters)
: BrowserMainParts(),
devtools_delegate_(NULL) {
CefContentBrowserClient* browser_client =
static_cast<CefContentBrowserClient*>(
content::GetContentClient()->browser());
browser_client->set_browser_main_parts(this);
}
CefBrowserMainParts::~CefBrowserMainParts() {
}
MessageLoop* CefBrowserMainParts::GetMainMessageLoop() {
return new CefBrowserMessageLoop();
}
int CefBrowserMainParts::PreCreateThreads() {
return 0;
}
void CefBrowserMainParts::PreMainMessageLoopRun() {
browser_context_.reset(new CefBrowserContext(this));
PlatformInitialize();
net::NetModule::SetResourceProvider(&ResourceProvider);
// Initialize the GpuDataManager before IO access restrictions are applied.
content::GpuDataManager::GetInstance();
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
std::string port_str =
command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
int port;
if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) {
devtools_delegate_ = new CefDevToolsDelegate(
port,
browser_context_->GetRequestContext());
} else {
DLOG(WARNING) << "Invalid http debugger port number " << port;
}
}
}
void CefBrowserMainParts::PostMainMessageLoopRun() {
PlatformCleanup();
if (devtools_delegate_)
devtools_delegate_->Stop();
browser_context_.reset();
}
bool CefBrowserMainParts::MainMessageLoopRun(int* result_code) {
return false;
}
ui::Clipboard* CefBrowserMainParts::GetClipboard() {
if (!clipboard_.get())
clipboard_.reset(new ui::Clipboard());
return clipboard_.get();
}

View File

@@ -0,0 +1,61 @@
// 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_BROWSER_BROWSER_MAIN_H_
#define CEF_LIBCEF_BROWSER_BROWSER_MAIN_H_
#pragma once
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_piece.h"
#include "content/public/browser/browser_main_parts.h"
namespace base {
class Thread;
}
namespace ui {
class Clipboard;
}
namespace content {
struct MainFunctionParams;
}
class CefBrowserContext;
class CefDevToolsDelegate;
class CefBrowserMainParts : public content::BrowserMainParts {
public:
explicit CefBrowserMainParts(const content::MainFunctionParams& parameters);
virtual ~CefBrowserMainParts();
virtual void PreEarlyInitialization() OVERRIDE {}
virtual void PostEarlyInitialization() OVERRIDE {}
virtual void PreMainMessageLoopStart() OVERRIDE {}
virtual MessageLoop* GetMainMessageLoop() OVERRIDE;
virtual void PostMainMessageLoopStart() OVERRIDE {}
virtual void ToolkitInitialized() OVERRIDE {}
virtual int PreCreateThreads() OVERRIDE;
virtual void PreMainMessageLoopRun() OVERRIDE;
virtual bool MainMessageLoopRun(int* result_code) OVERRIDE;
virtual void PostMainMessageLoopRun() OVERRIDE;
virtual void PostDestroyThreads() OVERRIDE {}
ui::Clipboard* GetClipboard();
CefBrowserContext* browser_context() const { return browser_context_.get(); }
private:
void PlatformInitialize();
void PlatformCleanup();
scoped_ptr<CefBrowserContext> browser_context_;
scoped_ptr<ui::Clipboard> clipboard_;
CefDevToolsDelegate* devtools_delegate_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserMainParts);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_MAIN_H_

View File

@@ -0,0 +1,16 @@
// 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 <gtk/gtk.h>
#include "libcef/browser/browser_main.h"
#include "base/string_piece.h"
void CefBrowserMainParts::PlatformInitialize() {
gtk_init(NULL, NULL);
}
void CefBrowserMainParts::PlatformCleanup() {
}

View File

@@ -0,0 +1,13 @@
// 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/browser/browser_main.h"
#include "base/string_piece.h"
void CefBrowserMainParts::PlatformInitialize() {
}
void CefBrowserMainParts::PlatformCleanup() {
}

View File

@@ -0,0 +1,35 @@
// 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 <windows.h>
#include <commctrl.h>
#include <Objbase.h>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_main.h"
#include "base/string_piece.h"
#include "base/win/resource_util.h"
void CefBrowserMainParts::PlatformInitialize() {
HRESULT res;
// Initialize common controls.
res = CoInitialize(NULL);
DCHECK(SUCCEEDED(res));
INITCOMMONCONTROLSEX InitCtrlEx;
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
InitCommonControlsEx(&InitCtrlEx);
// Start COM stuff.
res = OleInitialize(NULL);
DCHECK(SUCCEEDED(res));
// Register the browser window class.
CefBrowserHostImpl::RegisterWindowClass();
}
void CefBrowserMainParts::PlatformCleanup() {
}

View File

@@ -0,0 +1,54 @@
/// 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/browser/browser_message_filter.h"
#include "libcef/browser/origin_whitelist_impl.h"
#include "libcef/browser/scheme_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_messages.h"
#include "base/compiler_specific.h"
#include "base/bind.h"
CefBrowserMessageFilter::CefBrowserMessageFilter(
content::RenderProcessHost* host)
: host_(host),
channel_(NULL) {
}
CefBrowserMessageFilter::~CefBrowserMessageFilter() {
}
void CefBrowserMessageFilter::OnFilterAdded(IPC::Channel* channel) {
channel_ = channel;
}
void CefBrowserMessageFilter::OnFilterRemoved() {
}
bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CefBrowserMessageFilter, message)
IPC_MESSAGE_HANDLER(CefProcessHostMsg_RenderThreadStarted,
OnRenderThreadStarted)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void CefBrowserMessageFilter::OnRenderThreadStarted() {
// Execute registration on the UI thread.
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserMessageFilter::RegisterOnUIThread, this));
}
void CefBrowserMessageFilter::RegisterOnUIThread() {
CEF_REQUIRE_UIT();
// Send existing registrations to the new render process.
RegisterSchemesWithHost(host_);
RegisterCrossOriginWhitelistEntriesWithHost(host_);
}

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_BROWSER_BROWSER_MESSAGE_FILTER_H_
#define CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_FILTER_H_
#include <string>
#include "ipc/ipc_channel_proxy.h"
namespace content {
class RenderProcessHost;
}
// This class sends and receives control messages on the browser process.
class CefBrowserMessageFilter : public IPC::ChannelProxy::MessageFilter {
public:
explicit CefBrowserMessageFilter(content::RenderProcessHost* host);
virtual ~CefBrowserMessageFilter();
// 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.
void OnRenderThreadStarted();
void RegisterOnUIThread();
content::RenderProcessHost* host_;
IPC::Channel* channel_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserMessageFilter);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_FILTER_H_

View File

@@ -0,0 +1,46 @@
// 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/browser/browser_message_loop.h"
CefBrowserMessageLoop::CefBrowserMessageLoop()
: is_iterating_(true) {
}
CefBrowserMessageLoop::~CefBrowserMessageLoop() {
#if defined(OS_MACOSX)
// On Mac the MessageLoop::AutoRunState scope in Run() never exits so clear
// the state_ variable to avoid an assertion in the MessageLoop destructor.
state_ = NULL;
#endif
}
// static
CefBrowserMessageLoop* CefBrowserMessageLoop::current() {
MessageLoop* loop = MessageLoop::current();
DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
return static_cast<CefBrowserMessageLoop*>(loop);
}
bool CefBrowserMessageLoop::DoIdleWork() {
bool valueToRet = inherited::DoIdleWork();
if (is_iterating_)
pump_->Quit();
return valueToRet;
}
// Do a single interation of the UI message loop.
void CefBrowserMessageLoop::DoMessageLoopIteration() {
#if defined(OS_MACOSX)
Run();
#else
RunWithDispatcher(NULL);
#endif
}
// Run the UI message loop.
void CefBrowserMessageLoop::RunMessageLoop() {
is_iterating_ = false;
DoMessageLoopIteration();
}

View File

@@ -0,0 +1,40 @@
// 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_BROWSER_BROWSER_MESSAGE_LOOP_H_
#define CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_LOOP_H_
#pragma once
#include "base/basictypes.h"
#include "base/message_loop.h"
// Class used to process events on the current message loop.
class CefBrowserMessageLoop : public MessageLoopForUI {
typedef MessageLoopForUI inherited;
public:
CefBrowserMessageLoop();
virtual ~CefBrowserMessageLoop();
// Returns the MessageLoopForUI of the current thread.
static CefBrowserMessageLoop* current();
virtual bool DoIdleWork();
// Do a single interation of the UI message loop.
void DoMessageLoopIteration();
// Run the UI message loop.
void RunMessageLoop();
bool is_iterating() { return is_iterating_; }
private:
// True if the message loop is doing one iteration at a time.
bool is_iterating_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserMessageLoop);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_MESSAGE_LOOP_H_

View File

@@ -0,0 +1,172 @@
// Copyright (c) 2010 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/browser/browser_settings.h"
#include <string>
#include "include/internal/cef_types_wrappers.h"
#include "base/file_path.h"
#include "base/utf_string_conversions.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/gpu_data_manager.h"
#include "webkit/glue/webpreferences.h"
void BrowserToWebSettings(const CefBrowserSettings& cef, WebPreferences& web) {
if (cef.standard_font_family.length > 0)
web.standard_font_family = CefString(&cef.standard_font_family);
else
web.standard_font_family = ASCIIToUTF16("Times");
if (cef.fixed_font_family.length > 0)
web.fixed_font_family = CefString(&cef.fixed_font_family);
else
web.fixed_font_family = ASCIIToUTF16("Courier");
if (cef.serif_font_family.length > 0)
web.serif_font_family = CefString(&cef.serif_font_family);
else
web.serif_font_family = ASCIIToUTF16("Times");
if (cef.sans_serif_font_family.length > 0)
web.sans_serif_font_family = CefString(&cef.sans_serif_font_family);
else
web.sans_serif_font_family = ASCIIToUTF16("Helvetica");
// These two fonts below are picked from the intersection of
// Win XP font list and Vista font list :
// http://www.microsoft.com/typography/fonts/winxp.htm
// http://blogs.msdn.com/michkap/archive/2006/04/04/567881.aspx
// Some of them are installed only with CJK and complex script
// support enabled on Windows XP and are out of consideration here.
// (although we enabled both on our buildbots.)
// They (especially Impact for fantasy) are not typical cursive
// and fantasy fonts, but it should not matter for layout tests
// as long as they're available.
if (cef.cursive_font_family.length > 0) {
web.cursive_font_family = CefString(&cef.cursive_font_family);
} else {
#if defined(OS_MACOSX)
web.cursive_font_family = ASCIIToUTF16("Apple Chancery");
#else
web.cursive_font_family = ASCIIToUTF16("Comic Sans MS");
#endif
}
if (cef.fantasy_font_family.length > 0) {
web.fantasy_font_family = CefString(&cef.fantasy_font_family);
} else {
#if defined(OS_MACOSX)
web.fantasy_font_family = ASCIIToUTF16("Papyrus");
#else
web.fantasy_font_family = ASCIIToUTF16("Impact");
#endif
}
if (cef.default_font_size > 0)
web.default_font_size = cef.default_font_size;
else
web.default_font_size = 16;
if (cef.default_fixed_font_size > 0)
web.default_fixed_font_size = cef.default_fixed_font_size;
else
web.default_fixed_font_size = 13;
if (cef.minimum_font_size > 0)
web.minimum_font_size = cef.minimum_font_size;
else
web.minimum_font_size = 1;
if (cef.minimum_logical_font_size > 0)
web.minimum_logical_font_size = cef.minimum_logical_font_size;
else
web.minimum_logical_font_size = 9;
if (cef.default_encoding.length > 0)
web.default_encoding = CefString(&cef.default_encoding);
else
web.default_encoding = "ISO-8859-1";
web.javascript_enabled = !cef.javascript_disabled;
web.web_security_enabled = !cef.web_security_disabled;
web.javascript_can_open_windows_automatically =
!cef.javascript_open_windows_disallowed;
web.loads_images_automatically = !cef.image_load_disabled;
web.plugins_enabled = !cef.plugins_disabled;
web.dom_paste_enabled = !cef.dom_paste_disabled;
web.developer_extras_enabled = !cef.developer_tools_disabled;
web.inspector_settings.clear();
web.site_specific_quirks_enabled = !cef.site_specific_quirks_disabled;
web.shrinks_standalone_images_to_fit = cef.shrink_standalone_images_to_fit;
web.uses_universal_detector = cef.encoding_detector_enabled;
web.text_areas_are_resizable = !cef.text_area_resize_disabled;
web.java_enabled = !cef.java_disabled;
web.allow_scripts_to_close_windows = !cef.javascript_close_windows_disallowed;
web.uses_page_cache = !cef.page_cache_disabled;
web.remote_fonts_enabled = !cef.remote_fonts_disabled;
web.javascript_can_access_clipboard =
!cef.javascript_access_clipboard_disallowed;
web.xss_auditor_enabled = cef.xss_auditor_enabled;
web.local_storage_enabled = !cef.local_storage_disabled;
web.databases_enabled = !cef.databases_disabled;
web.application_cache_enabled = !cef.application_cache_disabled;
web.tabs_to_links = !cef.tab_to_links_disabled;
web.caret_browsing_enabled = cef.caret_browsing_enabled;
web.hyperlink_auditing_enabled = !cef.hyperlink_auditing_disabled;
web.user_style_sheet_enabled = cef.user_style_sheet_enabled;
if (cef.user_style_sheet_location.length > 0) {
web.user_style_sheet_location =
GURL(std::string(CefString(&cef.user_style_sheet_location)));
}
web.author_and_user_styles_enabled = !cef.author_and_user_styles_disabled;
web.allow_universal_access_from_file_urls =
cef.universal_access_from_file_urls_allowed;
web.allow_file_access_from_file_urls = cef.file_access_from_file_urls_allowed;
web.experimental_webgl_enabled =
GpuProcessHost::gpu_enabled() && !cef.webgl_disabled;
web.gl_multisampling_enabled = web.experimental_webgl_enabled;
web.show_composited_layer_borders = false;
web.accelerated_compositing_enabled =
GpuProcessHost::gpu_enabled() && !cef.accelerated_compositing_disabled;
web.accelerated_layers_enabled = !cef.accelerated_layers_disabled;
web.accelerated_video_enabled = !cef.accelerated_video_disabled;
web.accelerated_2d_canvas_enabled =
GpuProcessHost::gpu_enabled() && !cef.accelerated_2d_canvas_disabled;
web.accelerated_painting_enabled =
GpuProcessHost::gpu_enabled() && cef.accelerated_painting_enabled;
web.accelerated_filters_enabled =
GpuProcessHost::gpu_enabled() && cef.accelerated_filters_enabled;
web.accelerated_plugins_enabled = !cef.accelerated_plugins_disabled;
web.memory_info_enabled = false;
web.fullscreen_enabled = cef.fullscreen_enabled;
// TODO(cef): The GPU black list will need to be initialized. See
// InitializeGpuDataManager() in chrome/browser/chrome_browser_main.cc.
{ // Certain GPU features might have been blacklisted.
content::GpuDataManager* gpu_data_manager =
content::GpuDataManager::GetInstance();
DCHECK(gpu_data_manager);
content::GpuFeatureType blacklist_flags =
gpu_data_manager->GetGpuFeatureType();
if (blacklist_flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)
web.accelerated_compositing_enabled = false;
if (blacklist_flags & content::GPU_FEATURE_TYPE_WEBGL)
web.experimental_webgl_enabled = false;
if (blacklist_flags & content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
web.accelerated_2d_canvas_enabled = false;
if (blacklist_flags & content::GPU_FEATURE_TYPE_MULTISAMPLING)
web.gl_multisampling_enabled = false;
// Accelerated video is slower than regular when using a software 3d
// rasterizer.
if (gpu_data_manager->ShouldUseSoftwareRendering())
web.accelerated_video_enabled = false;
}
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2010 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_BROWSER_BROWSER_SETTINGS_H_
#define CEF_LIBCEF_BROWSER_BROWSER_SETTINGS_H_
#pragma once
#include "include/internal/cef_types_wrappers.h"
struct WebPreferences;
void BrowserToWebSettings(const CefBrowserSettings& cef, WebPreferences& web);
#endif // CEF_LIBCEF_BROWSER_BROWSER_SETTINGS_H_

View File

@@ -0,0 +1,434 @@
// 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/browser/content_browser_client.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_main.h"
#include "libcef/browser/browser_message_filter.h"
#include "libcef/browser/browser_settings.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_switches.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "content/public/browser/access_token_store.h"
#include "content/public/browser/media_observer.h"
#include "content/public/common/content_switches.h"
#include "googleurl/src/gurl.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace {
// In-memory store for access tokens used by geolocation.
class CefAccessTokenStore : public content::AccessTokenStore {
public:
CefAccessTokenStore() {}
virtual void LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) OVERRIDE {
callback.Run(access_token_set_,
_Context->browser_context()->GetRequestContext());
}
virtual void SaveAccessToken(
const GURL& server_url, const string16& access_token) OVERRIDE {
access_token_set_[server_url] = access_token;
}
private:
AccessTokenSet access_token_set_;
};
} // namespace
class CefMediaObserver : public content::MediaObserver {
public:
CefMediaObserver() {}
virtual ~CefMediaObserver() {}
virtual void OnDeleteAudioStream(void* host, int stream_id) OVERRIDE {}
virtual void OnSetAudioStreamPlaying(void* host, int stream_id,
bool playing) OVERRIDE {}
virtual void OnSetAudioStreamStatus(void* host, int stream_id,
const std::string& status) OVERRIDE {}
virtual void OnSetAudioStreamVolume(void* host, int stream_id,
double volume) OVERRIDE {}
virtual void OnMediaEvent(int render_process_id,
const media::MediaLogEvent& event) OVERRIDE {}
};
CefContentBrowserClient::CefContentBrowserClient()
: browser_main_parts_(NULL) {
}
CefContentBrowserClient::~CefContentBrowserClient() {
}
content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts(
const content::MainFunctionParams& parameters) {
return new CefBrowserMainParts(parameters);
}
content::WebContentsView*
CefContentBrowserClient::OverrideCreateWebContentsView(
content::WebContents* web_contents) {
return NULL;
}
content::WebContentsViewDelegate*
CefContentBrowserClient::GetWebContentsViewDelegate(
content::WebContents* web_contents) {
return NULL;
}
void CefContentBrowserClient::RenderViewHostCreated(
content::RenderViewHost* render_view_host) {
}
void CefContentBrowserClient::RenderProcessHostCreated(
content::RenderProcessHost* host) {
host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host));
}
content::WebUIControllerFactory*
CefContentBrowserClient::GetWebUIControllerFactory() {
return NULL;
}
GURL CefContentBrowserClient::GetEffectiveURL(
content::BrowserContext* browser_context, const GURL& url) {
return GURL();
}
bool CefContentBrowserClient::ShouldUseProcessPerSite(
content::BrowserContext* browser_context, const GURL& effective_url) {
return false;
}
bool CefContentBrowserClient::IsHandledURL(const GURL& url) {
return false;
}
bool CefContentBrowserClient::IsSuitableHost(
content::RenderProcessHost* process_host,
const GURL& site_url) {
return true;
}
bool CefContentBrowserClient::ShouldTryToUseExistingProcessHost(
content::BrowserContext* browser_context, const GURL& url) {
return false;
}
void CefContentBrowserClient::SiteInstanceGotProcess(
content::SiteInstance* site_instance) {
}
void CefContentBrowserClient::SiteInstanceDeleting(
content::SiteInstance* site_instance) {
}
bool CefContentBrowserClient::ShouldSwapProcessesForNavigation(
const GURL& current_url,
const GURL& new_url) {
return false;
}
std::string CefContentBrowserClient::GetCanonicalEncodingNameByAliasName(
const std::string& alias_name) {
return std::string();
}
void CefContentBrowserClient::AppendExtraCommandLineSwitches(
CommandLine* command_line, int child_process_id) {
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type == switches::kRendererProcess) {
// Propagate the following switches to the renderer command line (along
// with any associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
switches::kProductVersion,
switches::kLocale,
switches::kPackFilePath,
switches::kLocalesDirPath,
switches::kPackLoadingDisabled,
};
const CommandLine& browser_cmd = *CommandLine::ForCurrentProcess();
command_line->CopySwitchesFrom(browser_cmd, kSwitchNames,
arraysize(kSwitchNames));
}
}
std::string CefContentBrowserClient::GetApplicationLocale() {
return std::string();
}
std::string CefContentBrowserClient::GetAcceptLangs(
content::BrowserContext* context) {
return std::string();
}
SkBitmap* CefContentBrowserClient::GetDefaultFavicon() {
static SkBitmap empty;
return &empty;
}
bool CefContentBrowserClient::AllowAppCache(
const GURL& manifest_url,
const GURL& first_party,
content::ResourceContext* context) {
return true;
}
bool CefContentBrowserClient::AllowGetCookie(
const GURL& url,
const GURL& first_party,
const net::CookieList& cookie_list,
content::ResourceContext* context,
int render_process_id,
int render_view_id) {
return true;
}
bool CefContentBrowserClient::AllowSetCookie(
const GURL& url,
const GURL& first_party,
const std::string& cookie_line,
content::ResourceContext* context,
int render_process_id,
int render_view_id,
net::CookieOptions* options) {
return true;
}
bool CefContentBrowserClient::AllowSaveLocalState(
content::ResourceContext* context) {
return true;
}
bool CefContentBrowserClient::AllowWorkerDatabase(
const GURL& url,
const string16& name,
const string16& display_name,
unsigned long estimated_size, // NOLINT(runtime/int)
content::ResourceContext* context,
const std::vector<std::pair<int, int> >& render_views) {
return true;
}
bool CefContentBrowserClient::AllowWorkerFileSystem(
const GURL& url,
content::ResourceContext* context,
const std::vector<std::pair<int, int> >& render_views) {
return true;
}
bool CefContentBrowserClient::AllowWorkerIndexedDB(
const GURL& url,
const string16& name,
content::ResourceContext* context,
const std::vector<std::pair<int, int> >& render_views) {
return true;
}
content::QuotaPermissionContext*
CefContentBrowserClient::CreateQuotaPermissionContext() {
return NULL;
}
net::URLRequestContext* CefContentBrowserClient::OverrideRequestContextForURL(
const GURL& url, content::ResourceContext* context) {
return NULL;
}
void CefContentBrowserClient::OpenItem(const FilePath& path) {
}
void CefContentBrowserClient::ShowItemInFolder(const FilePath& path) {
}
void CefContentBrowserClient::AllowCertificateError(
int render_process_id,
int render_view_id,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
bool overridable,
const base::Callback<void(bool)>& callback,
bool* cancel_request) {
}
void CefContentBrowserClient::SelectClientCertificate(
int render_process_id,
int render_view_id,
const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) {
}
void CefContentBrowserClient::AddNewCertificate(
net::URLRequest* request,
net::X509Certificate* cert,
int render_process_id,
int render_view_id) {
}
bool CefContentBrowserClient::AllowSocketAPI(
content::BrowserContext* browser_context,
const GURL& url) {
return false;
}
void CefContentBrowserClient::RequestMediaAccessPermission(
const content::MediaStreamRequest* request,
const content::MediaResponseCallback& callback) {
CEF_CURRENTLY_ON_UIT();
content::MediaStreamDevices devices;
for (content::MediaStreamDeviceMap::const_iterator it =
request->devices.begin(); it != request->devices.end(); ++it) {
devices.push_back(*it->second.begin());
}
// TODO(cef): Give the user an opportunity to approve the device list or run
// the callback with an empty device list to cancel the request.
callback.Run(devices);
}
content::MediaObserver* CefContentBrowserClient::GetMediaObserver() {
// TODO(cef): Return NULL once it's supported. See crbug.com/116113.
if (!media_observer_.get())
media_observer_.reset(new CefMediaObserver());
return media_observer_.get();
}
void CefContentBrowserClient::RequestDesktopNotificationPermission(
const GURL& source_origin,
int callback_context,
int render_process_id,
int render_view_id) {
}
WebKit::WebNotificationPresenter::Permission
CefContentBrowserClient::CheckDesktopNotificationPermission(
const GURL& source_origin,
content::ResourceContext* context,
int render_process_id) {
return WebKit::WebNotificationPresenter::PermissionAllowed;
}
void CefContentBrowserClient::ShowDesktopNotification(
const content::ShowDesktopNotificationHostMsgParams& params,
int render_process_id,
int render_view_id,
bool worker) {
}
void CefContentBrowserClient::CancelDesktopNotification(
int render_process_id,
int render_view_id,
int notification_id) {
}
bool CefContentBrowserClient::CanCreateWindow(
const GURL& opener_url,
const GURL& origin,
WindowContainerType container_type,
content::ResourceContext* context,
int render_process_id) {
return true;
}
std::string CefContentBrowserClient::GetWorkerProcessTitle(
const GURL& url, content::ResourceContext* context) {
return std::string();
}
void CefContentBrowserClient::ResourceDispatcherHostCreated() {
}
content::SpeechRecognitionManagerDelegate*
CefContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
return NULL;
}
ui::Clipboard* CefContentBrowserClient::GetClipboard() {
return browser_main_parts_->GetClipboard();
}
net::NetLog* CefContentBrowserClient::GetNetLog() {
return NULL;
}
content::AccessTokenStore* CefContentBrowserClient::CreateAccessTokenStore() {
return new CefAccessTokenStore;
}
bool CefContentBrowserClient::IsFastShutdownPossible() {
return true;
}
void CefContentBrowserClient::OverrideWebkitPrefs(
content::RenderViewHost* rvh,
const GURL& url,
WebPreferences* prefs) {
CefRefPtr<CefBrowserHostImpl> browser = CefBrowserHostImpl::GetBrowserForHost(rvh);
DCHECK(browser.get());
// Populate WebPreferences based on CefBrowserSettings.
BrowserToWebSettings(browser->settings(), *prefs);
}
void CefContentBrowserClient::UpdateInspectorSetting(
content::RenderViewHost* rvh,
const std::string& key,
const std::string& value) {
}
void CefContentBrowserClient::ClearInspectorSettings(
content::RenderViewHost* rvh) {
}
void CefContentBrowserClient::BrowserURLHandlerCreated(
content::BrowserURLHandler* handler) {
}
void CefContentBrowserClient::ClearCache(content::RenderViewHost* rvh) {
}
void CefContentBrowserClient::ClearCookies(content::RenderViewHost* rvh) {
}
FilePath CefContentBrowserClient::GetDefaultDownloadDirectory() {
return FilePath();
}
std::string CefContentBrowserClient::GetDefaultDownloadName() {
return "download";
}
#if defined(OS_POSIX) && !defined(OS_MACOSX)
int CefContentBrowserClient::GetCrashSignalFD(
const CommandLine& command_line) {
return -1;
}
#endif
#if defined(OS_WIN)
const wchar_t* CefContentBrowserClient::GetResourceDllName() {
return NULL;
}
#endif
#if defined(USE_NSS)
crypto::CryptoModuleBlockingPasswordDelegate*
CefContentBrowserClient::GetCryptoPasswordDelegate(const GURL& url) {
return NULL;
}
#endif

View File

@@ -0,0 +1,205 @@
// 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_BROWSER_CONTENT_BROWSER_CLIENT_H_
#define CEF_LIBCEF_BROWSER_CONTENT_BROWSER_CLIENT_H_
#pragma once
#include <string>
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/content_browser_client.h"
class CefBrowserMainParts;
class CefMediaObserver;
namespace content {
class SiteInstance;
}
class CefContentBrowserClient : public content::ContentBrowserClient {
public:
CefContentBrowserClient();
virtual ~CefContentBrowserClient();
void set_browser_main_parts(CefBrowserMainParts* parts) {
browser_main_parts_ = parts;
}
CefBrowserMainParts* browser_main_parts() const {
return browser_main_parts_;
}
virtual content::BrowserMainParts* CreateBrowserMainParts(
const content::MainFunctionParams& parameters) OVERRIDE;
virtual content::WebContentsView* OverrideCreateWebContentsView(
content::WebContents* web_contents) OVERRIDE;
virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate(
content::WebContents* web_contents) OVERRIDE;
virtual void RenderViewHostCreated(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void RenderProcessHostCreated(
content::RenderProcessHost* host) OVERRIDE;
virtual content::WebUIControllerFactory* GetWebUIControllerFactory() OVERRIDE;
virtual GURL GetEffectiveURL(content::BrowserContext* browser_context,
const GURL& url) OVERRIDE;
virtual bool ShouldUseProcessPerSite(content::BrowserContext* browser_context,
const GURL& effective_url) OVERRIDE;
virtual bool IsHandledURL(const GURL& url) OVERRIDE;
virtual bool IsSuitableHost(content::RenderProcessHost* process_host,
const GURL& site_url) OVERRIDE;
virtual bool ShouldTryToUseExistingProcessHost(
content::BrowserContext* browser_context, const GURL& url) OVERRIDE;
virtual void SiteInstanceGotProcess(
content::SiteInstance* site_instance) OVERRIDE;
virtual void SiteInstanceDeleting(
content::SiteInstance* site_instance) OVERRIDE;
virtual bool ShouldSwapProcessesForNavigation(const GURL& current_url,
const GURL& new_url) OVERRIDE;
virtual std::string GetCanonicalEncodingNameByAliasName(
const std::string& alias_name) OVERRIDE;
virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
int child_process_id) OVERRIDE;
virtual std::string GetApplicationLocale() OVERRIDE;
virtual std::string GetAcceptLangs(
content::BrowserContext* context) OVERRIDE;
virtual SkBitmap* GetDefaultFavicon() OVERRIDE;
virtual bool AllowAppCache(const GURL& manifest_url,
const GURL& first_party,
content::ResourceContext* context) OVERRIDE;
virtual bool AllowGetCookie(const GURL& url,
const GURL& first_party,
const net::CookieList& cookie_list,
content::ResourceContext* context,
int render_process_id,
int render_view_id) OVERRIDE;
virtual bool AllowSetCookie(const GURL& url,
const GURL& first_party,
const std::string& cookie_line,
content::ResourceContext* context,
int render_process_id,
int render_view_id,
net::CookieOptions* options) OVERRIDE;
virtual bool AllowSaveLocalState(
content::ResourceContext* context) OVERRIDE;
virtual bool AllowWorkerDatabase(
const GURL& url,
const string16& name,
const string16& display_name,
unsigned long estimated_size, // NOLINT(runtime/int)
content::ResourceContext* context,
const std::vector<std::pair<int, int> >& render_views) OVERRIDE;
virtual bool AllowWorkerFileSystem(
const GURL& url,
content::ResourceContext* context,
const std::vector<std::pair<int, int> >& render_views) OVERRIDE;
virtual bool AllowWorkerIndexedDB(
const GURL& url,
const string16& name,
content::ResourceContext* context,
const std::vector<std::pair<int, int> >& render_views) OVERRIDE;
virtual net::URLRequestContext* OverrideRequestContextForURL(
const GURL& url, content::ResourceContext* context) OVERRIDE;
virtual content::QuotaPermissionContext* CreateQuotaPermissionContext()
OVERRIDE;
virtual void OpenItem(const FilePath& path) OVERRIDE;
virtual void ShowItemInFolder(const FilePath& path) OVERRIDE;
virtual void AllowCertificateError(
int render_process_id,
int render_view_id,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
bool overridable,
const base::Callback<void(bool)>& callback,
bool* cancel_request) OVERRIDE;
virtual void SelectClientCertificate(
int render_process_id,
int render_view_id,
const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE;
virtual void AddNewCertificate(
net::URLRequest* request,
net::X509Certificate* cert,
int render_process_id,
int render_view_id) OVERRIDE;
virtual void RequestMediaAccessPermission(
const content::MediaStreamRequest* request,
const content::MediaResponseCallback& callback) OVERRIDE;
virtual content::MediaObserver* GetMediaObserver() OVERRIDE;
virtual void RequestDesktopNotificationPermission(
const GURL& source_origin,
int callback_context,
int render_process_id,
int render_view_id) OVERRIDE;
virtual WebKit::WebNotificationPresenter::Permission
CheckDesktopNotificationPermission(
const GURL& origin,
content::ResourceContext* context,
int render_process_id) OVERRIDE;
virtual void ShowDesktopNotification(
const content::ShowDesktopNotificationHostMsgParams& params,
int render_process_id,
int render_view_id,
bool worker) OVERRIDE;
virtual void CancelDesktopNotification(
int render_process_id,
int render_view_id,
int notification_id) OVERRIDE;
virtual bool CanCreateWindow(
const GURL& opener_url,
const GURL& origin,
WindowContainerType container_type,
content::ResourceContext* context,
int render_process_id) OVERRIDE;
virtual std::string GetWorkerProcessTitle(
const GURL& url, content::ResourceContext* context) OVERRIDE;
virtual content::SpeechRecognitionManagerDelegate*
GetSpeechRecognitionManagerDelegate() OVERRIDE;
virtual void ResourceDispatcherHostCreated() OVERRIDE;
virtual ui::Clipboard* GetClipboard() OVERRIDE;
virtual net::NetLog* GetNetLog() OVERRIDE;
virtual content::AccessTokenStore* CreateAccessTokenStore() OVERRIDE;
virtual bool IsFastShutdownPossible() OVERRIDE;
virtual void OverrideWebkitPrefs(content::RenderViewHost* rvh,
const GURL& url,
WebPreferences* prefs) OVERRIDE;
virtual void UpdateInspectorSetting(content::RenderViewHost* rvh,
const std::string& key,
const std::string& value) OVERRIDE;
virtual void ClearInspectorSettings(content::RenderViewHost* rvh) OVERRIDE;
virtual void BrowserURLHandlerCreated(content::BrowserURLHandler* handler)
OVERRIDE;
virtual void ClearCache(content::RenderViewHost* rvh) OVERRIDE;
virtual void ClearCookies(content::RenderViewHost* rvh) OVERRIDE;
virtual FilePath GetDefaultDownloadDirectory() OVERRIDE;
virtual std::string GetDefaultDownloadName() OVERRIDE;
virtual bool AllowSocketAPI(content::BrowserContext* browser_context,
const GURL& url) OVERRIDE;
#if defined(OS_POSIX) && !defined(OS_MACOSX)
virtual int GetCrashSignalFD(const CommandLine& command_line) OVERRIDE;
#endif
#if defined(OS_WIN)
virtual const wchar_t* GetResourceDllName() OVERRIDE;
#endif
#if defined(USE_NSS)
virtual
crypto::CryptoModuleBlockingPasswordDelegate* GetCryptoPasswordDelegate(
const GURL& url) OVERRIDE;
#endif
private:
CefBrowserMainParts* browser_main_parts_;
scoped_ptr<CefMediaObserver> media_observer_;
};
#endif // CEF_LIBCEF_BROWSER_CONTENT_BROWSER_CLIENT_H_

399
libcef/browser/context.cc Normal file
View File

@@ -0,0 +1,399 @@
// 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/browser/context.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_main.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/main_delegate.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/common/content_switches.h"
#include "sandbox/src/sandbox_types.h"
#include "ui/base/ui_base_switches.h"
#if defined(OS_MACOSX)
#include "libcef/browser/application_mac.h"
#endif
#if defined(OS_WIN)
#include "content/public/app/startup_helper_win.h"
#endif
// Both the CefContext constuctor and the CefContext::RemoveBrowser method need
// to initialize or reset to the same value.
const int kNextBrowserIdReset = 1;
// Global CefContext pointer
CefRefPtr<CefContext> _Context;
namespace {
// Used in multi-threaded message loop mode to observe shutdown of the UI
// thread.
class DestructionObserver : public MessageLoop::DestructionObserver {
public:
explicit DestructionObserver(base::WaitableEvent *event) : event_(event) {}
virtual void WillDestroyCurrentMessageLoop() {
MessageLoop::current()->RemoveDestructionObserver(this);
event_->Signal();
delete this;
}
private:
base::WaitableEvent *event_;
};
} // namespace
int CefExecuteProcess(const CefMainArgs& args,
CefRefPtr<CefApp> application) {
CommandLine command_line(CommandLine::NO_PROGRAM);
#if defined(OS_WIN)
command_line.ParseFromString(::GetCommandLineW());
#else
command_line.InitFromArgv(args.argc, args.argv);
#endif
// If no process type is specified then it represents the browser process and
// we do nothing.
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty())
return -1;
#if defined(OS_MACOSX)
// Create the CefCrApplication instance.
CefCrApplicationCreate();
#endif
CefMainDelegate main_delegate(application);
// Execute the secondary process.
#if defined(OS_WIN)
sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info);
return content::ContentMain(args.instance, &sandbox_info, &main_delegate);
#else
return content::ContentMain(args.argc, const_cast<const char**>(args.argv),
&main_delegate);
#endif
}
bool CefInitialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application) {
// Return true if the global context already exists.
if (_Context.get())
return true;
if (settings.size != sizeof(cef_settings_t)) {
NOTREACHED() << "invalid CefSettings structure size";
return false;
}
// Create the new global context object.
_Context = new CefContext();
// Initialize the global context.
return _Context->Initialize(args, settings, application);
}
void CefShutdown() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return;
}
// Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) {
NOTREACHED() << "called on invalid thread";
return;
}
// Shut down the global context. This will block until shutdown is complete.
_Context->Shutdown();
// Delete the global context object.
_Context = NULL;
}
void CefDoMessageLoopWork() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return;
}
// Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) {
NOTREACHED() << "called on invalid thread";
return;
}
CefBrowserMessageLoop::current()->DoMessageLoopIteration();
}
void CefRunMessageLoop() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return;
}
// Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) {
NOTREACHED() << "called on invalid thread";
return;
}
CefBrowserMessageLoop::current()->RunMessageLoop();
}
void CefQuitMessageLoop() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return;
}
// Must always be called on the same thread as Initialize.
if (!_Context->OnInitThread()) {
NOTREACHED() << "called on invalid thread";
return;
}
CefBrowserMessageLoop::current()->Quit();
}
// CefContext
CefContext::CefContext()
: initialized_(false),
shutting_down_(false),
init_thread_id_(0),
next_browser_id_(kNextBrowserIdReset) {
}
CefContext::~CefContext() {
if (!shutting_down_)
Shutdown();
}
bool CefContext::Initialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application) {
init_thread_id_ = base::PlatformThread::CurrentId();
settings_ = settings;
cache_path_ = FilePath(CefString(&settings.cache_path));
if (settings.multi_threaded_message_loop) {
// TODO(cef): Figure out if we can support this.
NOTIMPLEMENTED();
return false;
}
main_delegate_.reset(new CefMainDelegate(application));
main_runner_.reset(content::ContentMainRunner::Create());
int exit_code;
// Initialize the content runner.
#if defined(OS_WIN)
sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info);
exit_code = main_runner_->Initialize(args.instance, &sandbox_info,
main_delegate_.get());
#else
exit_code = main_runner_->Initialize(args.argc,
const_cast<const char**>(args.argv),
main_delegate_.get());
#endif
DCHECK_LT(exit_code, 0);
if (exit_code >= 0)
return false;
// Run the process. Results in a call to CefMainDelegate::RunKnownProcess()
// which will create the browser runner and message loop without blocking.
exit_code = main_runner_->Run();
initialized_ = true;
return true;
}
void CefContext::Shutdown() {
// Must always be called on the same thread as Initialize.
DCHECK(OnInitThread());
shutting_down_ = true;
if (settings_.multi_threaded_message_loop) {
// Events that will be used to signal when shutdown is complete. Start in
// non-signaled mode so that the event will block.
base::WaitableEvent browser_shutdown_event(false, false);
base::WaitableEvent uithread_shutdown_event(false, false);
// Finish shutdown on the UI thread.
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefContext::FinishShutdownOnUIThread, this,
&browser_shutdown_event, &uithread_shutdown_event));
// Block until browser shutdown is complete.
browser_shutdown_event.Wait();
FinalizeShutdown();
// Block until UI thread shutdown is complete.
uithread_shutdown_event.Wait();
} else {
// Finish shutdown on the current thread, which should be the UI thread.
FinishShutdownOnUIThread(NULL, NULL);
FinalizeShutdown();
}
}
bool CefContext::OnInitThread() {
return (base::PlatformThread::CurrentId() == init_thread_id_);
}
bool CefContext::AddBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
bool found = false;
AutoLock lock_scope(this);
// check that the browser isn't already in the list before adding
BrowserList::const_iterator it = browserlist_.begin();
for (; it != browserlist_.end(); ++it) {
if (it->get() == browser.get()) {
found = true;
break;
}
}
if (!found) {
browser->SetUniqueId(next_browser_id_++);
browserlist_.push_back(browser);
}
return !found;
}
bool CefContext::RemoveBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
bool deleted = false;
{
AutoLock lock_scope(this);
BrowserList::iterator it = browserlist_.begin();
for (; it != browserlist_.end(); ++it) {
if (it->get() == browser.get()) {
browserlist_.erase(it);
deleted = true;
break;
}
}
if (browserlist_.empty())
next_browser_id_ = kNextBrowserIdReset;
}
return deleted;
}
CefRefPtr<CefBrowserHostImpl> CefContext::GetBrowserByID(int id) {
AutoLock lock_scope(this);
BrowserList::const_iterator it = browserlist_.begin();
for (; it != browserlist_.end(); ++it) {
if (it->get()->unique_id() == id)
return it->get();
}
return NULL;
}
CefRefPtr<CefBrowserHostImpl> CefContext::GetBrowserByRoutingID(
int render_process_id, int render_view_id) {
AutoLock lock_scope(this);
BrowserList::const_iterator it = browserlist_.begin();
for (; it != browserlist_.end(); ++it) {
if (it->get()->render_process_id() == render_process_id &&
(render_view_id == 0 ||
it->get()->render_view_id() == render_view_id)) {
return it->get();
}
}
return NULL;
}
CefRefPtr<CefApp> CefContext::application() const {
return main_delegate_->content_client()->application();
}
CefBrowserContext* CefContext::browser_context() const {
return main_delegate_->browser_client()->browser_main_parts()->
browser_context();
}
void CefContext::FinishShutdownOnUIThread(
base::WaitableEvent* browser_shutdown_event,
base::WaitableEvent* uithread_shutdown_event) {
CEF_REQUIRE_UIT();
BrowserList list;
{
AutoLock lock_scope(this);
if (!browserlist_.empty()) {
list = browserlist_;
browserlist_.clear();
}
}
// Destroy any remaining browser windows.
if (!list.empty()) {
BrowserList::iterator it = list.begin();
for (; it != list.end(); ++it)
(*it)->DestroyBrowser();
}
if (uithread_shutdown_event) {
// The destruction observer will signal the UI thread shutdown event when
// the UI thread has been destroyed.
MessageLoop::current()->AddDestructionObserver(
new DestructionObserver(uithread_shutdown_event));
// Signal the browser shutdown event now.
browser_shutdown_event->Signal();
}
}
void CefContext::FinalizeShutdown() {
// Shut down the browser runner.
main_delegate_->ShutdownBrowser();
// Shut down the content runner.
main_runner_->Shutdown();
main_runner_.reset(NULL);
main_delegate_.reset(NULL);
}

109
libcef/browser/context.h Normal file
View File

@@ -0,0 +1,109 @@
// 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_BROWSER_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_CONTEXT_H_
#pragma once
#include <list>
#include <map>
#include <string>
#include "include/cef_app.h"
#include "include/cef_base.h"
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/platform_thread.h"
namespace base {
class WaitableEvent;
}
namespace content {
class ContentMainRunner;
}
class CefBrowserContext;
class CefBrowserHostImpl;
class CefDevToolsDelegate;
class CefMainDelegate;
class CefContext : public CefBase {
public:
typedef std::list<CefRefPtr<CefBrowserHostImpl> > BrowserList;
CefContext();
~CefContext();
// These methods will be called on the main application thread.
bool Initialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application);
void Shutdown();
// Returns true if the current thread is the initialization thread.
bool OnInitThread();
// Returns true if the context is initialized.
bool initialized() { return initialized_; }
// Returns true if the context is shutting down.
bool shutting_down() { return shutting_down_; }
bool AddBrowser(CefRefPtr<CefBrowserHostImpl> browser);
bool RemoveBrowser(CefRefPtr<CefBrowserHostImpl> browser);
CefRefPtr<CefBrowserHostImpl> GetBrowserByID(int id);
CefRefPtr<CefBrowserHostImpl> GetBrowserByRoutingID(int render_process_id,
int render_view_id);
BrowserList* GetBrowserList() { return &browserlist_; }
// Retrieve the path at which cache data will be stored on disk. If empty,
// cache data will be stored in-memory.
const FilePath& cache_path() const { return cache_path_; }
const CefSettings& settings() const { return settings_; }
CefRefPtr<CefApp> application() const;
CefBrowserContext* browser_context() const;
private:
// Performs shutdown actions that need to occur on the UI thread before any
// threads are destroyed.
void FinishShutdownOnUIThread(base::WaitableEvent* browser_shutdown_event,
base::WaitableEvent* uithread_shutdown_event);
// Destroys the main runner and related objects.
void FinalizeShutdown();
// Track context state.
bool initialized_;
bool shutting_down_;
// The thread on which the context was initialized.
base::PlatformThreadId init_thread_id_;
CefSettings settings_;
FilePath cache_path_;
// Map of browsers that currently exist.
BrowserList browserlist_;
// Used for assigning unique IDs to browser instances.
int next_browser_id_;
scoped_ptr<CefMainDelegate> main_delegate_;
scoped_ptr<content::ContentMainRunner> main_runner_;
IMPLEMENT_REFCOUNTING(CefContext);
IMPLEMENT_LOCKING(CefContext);
};
// Global context object pointer.
extern CefRefPtr<CefContext> _Context;
// Helper macro that returns true if the global context is in a valid state.
#define CONTEXT_STATE_VALID() \
(_Context.get() && _Context->initialized() && !_Context->shutting_down())
#endif // CEF_LIBCEF_BROWSER_CONTEXT_H_

View File

@@ -0,0 +1,266 @@
// 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/browser/cookie_manager_impl.h"
#include <string>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/common/time_util.h"
#include "base/bind.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_context.h"
namespace {
// Callback class for visiting cookies.
class VisitCookiesCallback : public base::RefCounted<VisitCookiesCallback> {
public:
explicit VisitCookiesCallback(net::CookieMonster* cookie_monster,
CefRefPtr<CefCookieVisitor> visitor)
: cookie_monster_(cookie_monster),
visitor_(visitor) {
}
void Run(const net::CookieList& list) {
CEF_REQUIRE_IOT();
int total = list.size(), count = 0;
net::CookieList::const_iterator it = list.begin();
for (; it != list.end(); ++it, ++count) {
CefCookie cookie;
const net::CookieMonster::CanonicalCookie& cc = *(it);
CefString(&cookie.name).FromString(cc.Name());
CefString(&cookie.value).FromString(cc.Value());
CefString(&cookie.domain).FromString(cc.Domain());
CefString(&cookie.path).FromString(cc.Path());
cookie.secure = cc.IsSecure();
cookie.httponly = cc.IsHttpOnly();
cef_time_from_basetime(cc.CreationDate(), cookie.creation);
cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access);
cookie.has_expires = cc.DoesExpire();
if (cookie.has_expires)
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
bool deleteCookie = false;
bool keepLooping = visitor_->Visit(cookie, count, total, deleteCookie);
if (deleteCookie) {
cookie_monster_->DeleteCanonicalCookieAsync(cc,
net::CookieMonster::DeleteCookieCallback());
}
if (!keepLooping)
break;
}
}
private:
scoped_refptr<net::CookieMonster> cookie_monster_;
CefRefPtr<CefCookieVisitor> visitor_;
};
} // namespace
CefCookieManagerImpl::CefCookieManagerImpl(bool is_global)
: is_global_(is_global) {
}
CefCookieManagerImpl::~CefCookieManagerImpl() {
}
void CefCookieManagerImpl::Initialize(const CefString& path) {
if (is_global_)
SetGlobal();
else
SetStoragePath(path);
}
bool CefCookieManagerImpl::VisitAllCookies(
CefRefPtr<CefCookieVisitor> visitor) {
if (CEF_CURRENTLY_ON_IOT()) {
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_monster_, visitor));
cookie_monster_->GetAllCookiesAsync(
base::Bind(&VisitCookiesCallback::Run, callback.get()));
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::VisitAllCookies),
this, visitor));
}
return true;
}
bool CefCookieManagerImpl::VisitUrlCookies(
const CefString& url, bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) {
if (CEF_CURRENTLY_ON_IOT()) {
net::CookieOptions options;
if (includeHttpOnly)
options.set_include_httponly();
scoped_refptr<VisitCookiesCallback> callback(
new VisitCookiesCallback(cookie_monster_, visitor));
GURL gurl = GURL(url.ToString());
cookie_monster_->GetAllCookiesForURLWithOptionsAsync(gurl, options,
base::Bind(&VisitCookiesCallback::Run, callback.get()));
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::VisitUrlCookies),
this, url, includeHttpOnly, visitor));
}
return true;
}
bool CefCookieManagerImpl::SetCookie(const CefString& url,
const CefCookie& cookie) {
CEF_REQUIRE_IOT_RETURN(false);
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
return false;
std::string name = CefString(&cookie.name).ToString();
std::string value = CefString(&cookie.value).ToString();
std::string domain = CefString(&cookie.domain).ToString();
std::string path = CefString(&cookie.path).ToString();
base::Time expiration_time;
if (cookie.has_expires)
cef_time_to_basetime(cookie.expires, expiration_time);
cookie_monster_->SetCookieWithDetailsAsync(gurl, name, value, domain, path,
expiration_time, cookie.secure, cookie.httponly,
net::CookieStore::SetCookiesCallback());
return true;
}
bool CefCookieManagerImpl::DeleteCookies(const CefString& url,
const CefString& cookie_name) {
CEF_REQUIRE_IOT_RETURN(false);
if (url.empty()) {
// Delete all cookies.
cookie_monster_->DeleteAllAsync(net::CookieMonster::DeleteCallback());
return true;
}
GURL gurl = GURL(url.ToString());
if (!gurl.is_valid())
return false;
if (cookie_name.empty()) {
// Delete all matching host cookies.
cookie_monster_->DeleteAllForHostAsync(gurl,
net::CookieMonster::DeleteCallback());
} else {
// Delete all matching host and domain cookies.
cookie_monster_->DeleteCookieAsync(gurl, cookie_name, base::Closure());
}
return true;
}
bool CefCookieManagerImpl::SetStoragePath(const CefString& path) {
if (CEF_CURRENTLY_ON_IOT()) {
FilePath new_path;
if (!path.empty())
new_path = FilePath(path);
if (is_global_) {
// Global path changes are handled by the request context.
CefURLRequestContextGetter* getter =
static_cast<CefURLRequestContextGetter*>(
_Context->browser_context()->GetRequestContext());
getter->SetCookieStoragePath(new_path);
cookie_monster_ = getter->GetURLRequestContext()->cookie_store()->
GetCookieMonster();
return true;
}
if (cookie_monster_ && ((storage_path_.empty() && path.empty()) ||
storage_path_ == new_path)) {
// The path has not changed so don't do anything.
return true;
}
scoped_refptr<SQLitePersistentCookieStore> persistent_store;
if (!new_path.empty()) {
if (file_util::CreateDirectory(new_path)) {
const FilePath& cookie_path = new_path.AppendASCII("Cookies");
persistent_store = new SQLitePersistentCookieStore(cookie_path, false);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
storage_path_.clear();
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
cookie_monster_ = new net::CookieMonster(persistent_store.get(), NULL);
storage_path_ = new_path;
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::SetStoragePath),
this, path));
}
return true;
}
void CefCookieManagerImpl::SetGlobal() {
if (CEF_CURRENTLY_ON_IOT()) {
cookie_monster_ = _Context->browser_context()->GetRequestContext()->
GetURLRequestContext()->cookie_store()->GetCookieMonster();
DCHECK(cookie_monster_);
} else {
// Execute on the IO thread.
CEF_POST_TASK(CEF_IOT, base::Bind(&CefCookieManagerImpl::SetGlobal, this));
}
}
// CefCookieManager methods ----------------------------------------------------
// static
CefRefPtr<CefCookieManager> CefCookieManager::GetGlobalManager() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return NULL;
}
CefRefPtr<CefCookieManagerImpl> manager(new CefCookieManagerImpl(true));
manager->Initialize(CefString());
return manager.get();
}
// static
CefRefPtr<CefCookieManager> CefCookieManager::CreateManager(
const CefString& path) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return NULL;
}
CefRefPtr<CefCookieManagerImpl> manager(new CefCookieManagerImpl(false));
manager->Initialize(path);
return manager.get();
}

View File

@@ -0,0 +1,43 @@
// 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_BROWSER_COOKIE_MANAGER_IMPL_H_
#define CEF_LIBCEF_BROWSER_COOKIE_MANAGER_IMPL_H_
#include "include/cef_cookie.h"
#include "base/file_path.h"
#include "net/cookies/cookie_monster.h"
// Implementation of the CefCookieManager interface.
class CefCookieManagerImpl : public CefCookieManager {
public:
CefCookieManagerImpl(bool is_global);
~CefCookieManagerImpl();
// Initialize the cookie manager.
void Initialize(const CefString& path);
// CefCookieManager methods.
virtual bool VisitAllCookies(CefRefPtr<CefCookieVisitor> visitor) OVERRIDE;
virtual bool VisitUrlCookies(const CefString& url, bool includeHttpOnly,
CefRefPtr<CefCookieVisitor> visitor) OVERRIDE;
virtual bool SetCookie(const CefString& url,
const CefCookie& cookie) OVERRIDE;
virtual bool DeleteCookies(const CefString& url,
const CefString& cookie_name) OVERRIDE;
virtual bool SetStoragePath(const CefString& path) OVERRIDE;
net::CookieMonster* cookie_monster() { return cookie_monster_; }
private:
void SetGlobal();
scoped_refptr<net::CookieMonster> cookie_monster_;
bool is_global_;
FilePath storage_path_;
IMPLEMENT_REFCOUNTING(CefCookieManagerImpl);
};
#endif // CEF_LIBCEF_BROWSER_COOKIE_MANAGER_IMPL_H_

View File

@@ -0,0 +1,50 @@
// 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/browser/devtools_delegate.h"
#include <algorithm>
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/common/content_client.h"
#include "grit/cef_resources.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/resource/resource_bundle.h"
CefDevToolsDelegate::CefDevToolsDelegate(
int port,
net::URLRequestContextGetter* context_getter)
: context_getter_(context_getter) {
devtools_http_handler_ = content::DevToolsHttpHandler::Start(
"127.0.0.1",
port,
"",
this);
}
CefDevToolsDelegate::~CefDevToolsDelegate() {
}
void CefDevToolsDelegate::Stop() {
// The call below destroys this.
devtools_http_handler_->Stop();
}
std::string CefDevToolsDelegate::GetDiscoveryPageHTML() {
return content::GetContentClient()->GetDataResource(
IDR_CEF_DEVTOOLS_DISCOVERY_PAGE).as_string();
}
net::URLRequestContext*
CefDevToolsDelegate::GetURLRequestContext() {
return context_getter_->GetURLRequestContext();
}
bool CefDevToolsDelegate::BundlesFrontendResources() {
return true;
}
std::string CefDevToolsDelegate::GetFrontendResourcesBaseURL() {
return "";
}

View File

@@ -0,0 +1,44 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_DEVTOOLS_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_DEVTOOLS_DELEGATE_H_
#pragma once
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
namespace net {
class URLRequestContextGetter;
}
namespace content {
class DevToolsHttpHandler;
}
class CefDevToolsDelegate : public content::DevToolsHttpHandlerDelegate {
public:
CefDevToolsDelegate(int port, net::URLRequestContextGetter* context_getter);
virtual ~CefDevToolsDelegate();
// Stops http server.
void Stop();
// DevToolsHttpProtocolHandler::Delegate overrides.
virtual std::string GetDiscoveryPageHTML() OVERRIDE;
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
virtual bool BundlesFrontendResources() OVERRIDE;
virtual std::string GetFrontendResourcesBaseURL() OVERRIDE;
private:
net::URLRequestContextGetter* context_getter_;
content::DevToolsHttpHandler* devtools_http_handler_;
DISALLOW_COPY_AND_ASSIGN(CefDevToolsDelegate);
};
#endif // CEF_LIBCEF_BROWSER_DEVTOOLS_DELEGATE_H_

View File

@@ -0,0 +1,141 @@
// 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/browser/download_manager_delegate.h"
#if defined(OS_WIN)
#include <windows.h>
#include <commdlg.h>
#endif
#include "base/bind.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "content/browser/download/download_state_info.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "net/base/net_util.h"
using content::BrowserThread;
using content::DownloadItem;
using content::DownloadManager;
using content::WebContents;
CefDownloadManagerDelegate::CefDownloadManagerDelegate()
: download_manager_(NULL) {
}
CefDownloadManagerDelegate::~CefDownloadManagerDelegate() {
}
void CefDownloadManagerDelegate::SetDownloadManager(
DownloadManager* download_manager) {
download_manager_ = download_manager;
}
content::DownloadId CefDownloadManagerDelegate::GetNextId() {
static int next_id;
return content::DownloadId(this, ++next_id);
}
bool CefDownloadManagerDelegate::ShouldStartDownload(int32 download_id) {
DownloadItem* download =
download_manager_->GetActiveDownloadItem(download_id);
DownloadStateInfo state = download->GetStateInfo();
if (!state.force_file_name.empty())
return true;
FilePath generated_name = net::GenerateFileName(
download->GetURL(),
download->GetContentDisposition(),
download->GetReferrerCharset(),
download->GetSuggestedFilename(),
download->GetMimeType(),
"download");
// Since we have no download UI, show the user a dialog always.
state.prompt_user_for_save_location = true;
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
base::Bind(
&CefDownloadManagerDelegate::GenerateFilename,
this, download_id, state, generated_name));
return false;
}
void CefDownloadManagerDelegate::ChooseDownloadPath(
WebContents* web_contents,
const FilePath& suggested_path,
int32 download_id) {
FilePath result;
#if defined(OS_WIN)
std::wstring file_part = FilePath(suggested_path).BaseName().value();
wchar_t file_name[MAX_PATH];
base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name));
OPENFILENAME save_as;
ZeroMemory(&save_as, sizeof(save_as));
save_as.lStructSize = sizeof(OPENFILENAME);
save_as.hwndOwner = web_contents->GetNativeView();
save_as.lpstrFile = file_name;
save_as.nMaxFile = arraysize(file_name);
std::wstring directory;
if (!suggested_path.empty())
directory = suggested_path.DirName().value();
save_as.lpstrInitialDir = directory.c_str();
save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING |
OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
if (GetSaveFileName(&save_as))
result = FilePath(std::wstring(save_as.lpstrFile));
#else
NOTIMPLEMENTED();
#endif
if (result.empty()) {
download_manager_->FileSelectionCanceled(download_id);
} else {
download_manager_->FileSelected(result, download_id);
}
}
void CefDownloadManagerDelegate::GenerateFilename(
int32 download_id,
DownloadStateInfo state,
const FilePath& generated_name) {
if (state.suggested_path.empty()) {
state.suggested_path = download_manager_->GetBrowserContext()->GetPath().
Append(FILE_PATH_LITERAL("Downloads"));
if (!file_util::PathExists(state.suggested_path))
file_util::CreateDirectory(state.suggested_path);
}
state.suggested_path = state.suggested_path.Append(generated_name);
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(
&CefDownloadManagerDelegate::RestartDownload,
this, download_id, state));
}
void CefDownloadManagerDelegate::RestartDownload(
int32 download_id,
DownloadStateInfo state) {
DownloadItem* download =
download_manager_->GetActiveDownloadItem(download_id);
if (!download)
return;
download->SetFileCheckResults(state);
download_manager_->RestartDownload(download_id);
}

View File

@@ -0,0 +1,50 @@
// 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_BROWSER_DOWNLOAD_MANAGER_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_DOWNLOAD_MANAGER_DELEGATE_H_
#pragma once
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "content/public/browser/download_manager_delegate.h"
struct DownloadStateInfo;
namespace content {
class DownloadManager;
}
class CefDownloadManagerDelegate
: public content::DownloadManagerDelegate,
public base::RefCountedThreadSafe<CefDownloadManagerDelegate> {
public:
CefDownloadManagerDelegate();
void SetDownloadManager(content::DownloadManager* manager);
// DownloadManagerDelegate methods.
virtual content::DownloadId GetNextId() OVERRIDE;
virtual bool ShouldStartDownload(int32 download_id) OVERRIDE;
virtual void ChooseDownloadPath(content::WebContents* web_contents,
const FilePath& suggested_path,
int32 download_id) OVERRIDE;
private:
friend class base::RefCountedThreadSafe<CefDownloadManagerDelegate>;
virtual ~CefDownloadManagerDelegate();
void GenerateFilename(int32 download_id,
DownloadStateInfo state,
const FilePath& generated_name);
void RestartDownload(int32 download_id,
DownloadStateInfo state);
content::DownloadManager* download_manager_;
DISALLOW_COPY_AND_ASSIGN(CefDownloadManagerDelegate);
};
#endif // CEF_LIBCEF_BROWSER_DOWNLOAD_MANAGER_DELEGATE_H_

View File

@@ -0,0 +1,231 @@
// 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/browser/frame_host_impl.h"
#include "include/cef_request.h"
#include "include/cef_stream.h"
#include "include/cef_v8.h"
#include "libcef/common/cef_messages.h"
#include "libcef/browser/browser_host_impl.h"
namespace {
// Implementation of CommandResponseHandler for calling a CefStringVisitor.
class StringVisitHandler : public CefResponseManager::Handler {
public:
explicit StringVisitHandler(CefRefPtr<CefStringVisitor> visitor)
: visitor_(visitor) {
}
virtual void OnResponse(const Cef_Response_Params& params) OVERRIDE {
visitor_->Visit(params.response);
}
private:
CefRefPtr<CefStringVisitor> visitor_;
IMPLEMENT_REFCOUNTING(StringVisitHandler);
};
// Implementation of CommandResponseHandler for calling ViewText().
class ViewTextHandler : public CefResponseManager::Handler {
public:
explicit ViewTextHandler(CefRefPtr<CefFrameHostImpl> frame)
: frame_(frame) {
}
virtual void OnResponse(const Cef_Response_Params& params) OVERRIDE {
CefRefPtr<CefBrowser> browser = frame_->GetBrowser();
if (browser.get()) {
static_cast<CefBrowserHostImpl*>(browser.get())->ViewText(
params.response);
}
}
private:
CefRefPtr<CefFrameHostImpl> frame_;
IMPLEMENT_REFCOUNTING(ViewTextHandler);
};
} // namespace
CefFrameHostImpl::CefFrameHostImpl(CefBrowserHostImpl* browser,
int64 frame_id,
bool is_main_frame)
: frame_id_(frame_id),
is_main_frame_(is_main_frame),
browser_(browser),
is_focused_(false),
parent_frame_id_(kInvalidFrameId) {
}
CefFrameHostImpl::~CefFrameHostImpl() {
}
bool CefFrameHostImpl::IsValid() {
base::AutoLock lock_scope(state_lock_);
return (browser_ != NULL);
}
void CefFrameHostImpl::Undo() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "Undo", NULL);
}
void CefFrameHostImpl::Redo() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "Redo", NULL);
}
void CefFrameHostImpl::Cut() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "Cut", NULL);
}
void CefFrameHostImpl::Copy() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "Copy", NULL);
}
void CefFrameHostImpl::Paste() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "Paste", NULL);
}
void CefFrameHostImpl::Delete() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "Delete", NULL);
}
void CefFrameHostImpl::SelectAll() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "SelectAll", NULL);
}
void CefFrameHostImpl::ViewSource() {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId)
browser_->SendCommand(frame_id_, "GetSource", new ViewTextHandler(this));
}
void CefFrameHostImpl::GetSource(CefRefPtr<CefStringVisitor> visitor) {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId) {
browser_->SendCommand(frame_id_, "GetSource",
new StringVisitHandler(visitor));
}
}
void CefFrameHostImpl::GetText(CefRefPtr<CefStringVisitor> visitor) {
base::AutoLock lock_scope(state_lock_);
if (browser_ && frame_id_ != kInvalidFrameId) {
browser_->SendCommand(frame_id_, "GetText",
new StringVisitHandler(visitor));
}
}
void CefFrameHostImpl::LoadRequest(CefRefPtr<CefRequest> request) {
base::AutoLock lock_scope(state_lock_);
if (browser_)
browser_->LoadRequest((is_main_frame_ ? kMainFrameId : frame_id_), request);
}
void CefFrameHostImpl::LoadURL(const CefString& url) {
base::AutoLock lock_scope(state_lock_);
if (browser_)
browser_->LoadURL((is_main_frame_ ? kMainFrameId : frame_id_), url);
}
void CefFrameHostImpl::LoadString(const CefString& string,
const CefString& url) {
base::AutoLock lock_scope(state_lock_);
if (browser_) {
browser_->LoadString((is_main_frame_ ? kMainFrameId : frame_id_), string,
url);
}
}
void CefFrameHostImpl::ExecuteJavaScript(const CefString& jsCode,
const CefString& scriptUrl,
int startLine) {
base::AutoLock lock_scope(state_lock_);
if (browser_) {
browser_->SendCode((is_main_frame_ ? kMainFrameId : frame_id_), true,
jsCode, scriptUrl, startLine, NULL);
}
}
bool CefFrameHostImpl::IsMain() {
return is_main_frame_;
}
bool CefFrameHostImpl::IsFocused() {
base::AutoLock lock_scope(state_lock_);
return is_focused_;
}
CefString CefFrameHostImpl::GetName() {
base::AutoLock lock_scope(state_lock_);
return name_;
}
int64 CefFrameHostImpl::GetIdentifier() {
return frame_id_;
}
CefRefPtr<CefFrame> CefFrameHostImpl::GetParent() {
base::AutoLock lock_scope(state_lock_);
if (is_main_frame_ || parent_frame_id_ == kInvalidFrameId)
return NULL;
if (browser_)
return browser_->GetFrame(parent_frame_id_);
return NULL;
}
CefString CefFrameHostImpl::GetURL() {
base::AutoLock lock_scope(state_lock_);
return url_;
}
CefRefPtr<CefBrowser> CefFrameHostImpl::GetBrowser() {
base::AutoLock lock_scope(state_lock_);
return browser_;
}
void CefFrameHostImpl::SetFocused(bool focused) {
base::AutoLock lock_scope(state_lock_);
is_focused_ = focused;
}
void CefFrameHostImpl::SetURL(const CefString& url) {
base::AutoLock lock_scope(state_lock_);
url_ = url;
}
void CefFrameHostImpl::SetName(const CefString& name) {
base::AutoLock lock_scope(state_lock_);
name_ = name;
}
void CefFrameHostImpl::SetParentId(int64 frame_id) {
base::AutoLock lock_scope(state_lock_);
parent_frame_id_ = frame_id;
}
CefRefPtr<CefV8Context> CefFrameHostImpl::GetV8Context() {
NOTREACHED() << "GetV8Context cannot be called from the browser process";
return NULL;
}
void CefFrameHostImpl::Detach() {
base::AutoLock lock_scope(state_lock_);
browser_ = NULL;
}

View File

@@ -0,0 +1,83 @@
// 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_BROWSER_FRAME_HOST_IMPL_H_
#define CEF_LIBCEF_BROWSER_FRAME_HOST_IMPL_H_
#pragma once
#include <string>
#include "include/cef_frame.h"
#include "base/synchronization/lock.h"
class CefBrowserHostImpl;
// Implementation of CefFrame. CefFrameHostImpl objects are owned by the
// CefBrowerHostImpl and will be detached when the browser is notified that the
// associated renderer WebFrame will close.
class CefFrameHostImpl : public CefFrame {
public:
CefFrameHostImpl(CefBrowserHostImpl* browser,
int64 frame_id,
bool is_main_frame);
virtual ~CefFrameHostImpl();
// CefFrame methods
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 SetFocused(bool focused);
void SetURL(const CefString& url);
void SetName(const CefString& name);
void SetParentId(int64 frame_id);
// Detach the frame from the browser.
void Detach();
// kMainFrameId must be -1 to align with renderer expectations.
static const int64 kMainFrameId = -1;
static const int64 kFocusedFrameId = -2;
static const int64 kUnspecifiedFrameId = -3;
static const int64 kInvalidFrameId = -4;
protected:
int64 frame_id_;
bool is_main_frame_;
// Volatile state information. All access must be protected by the state lock.
base::Lock state_lock_;
CefBrowserHostImpl* browser_;
bool is_focused_;
CefString url_;
CefString name_;
int64 parent_frame_id_;
IMPLEMENT_REFCOUNTING(CefFrameHostImpl);
DISALLOW_EVIL_CONSTRUCTORS(CefFrameHostImpl);
};
#endif // CEF_LIBCEF_BROWSER_FRAME_HOST_IMPL_H_

View File

@@ -0,0 +1,20 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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/browser/navigate_params.h"
CefNavigateParams::CefNavigateParams(
const GURL& a_url,
content::PageTransition a_transition)
: url(a_url),
frame_id(-1),
disposition(CURRENT_TAB),
transition(a_transition),
is_renderer_initiated(false),
user_gesture(true) {
}
CefNavigateParams::~CefNavigateParams() {
}

View File

@@ -0,0 +1,84 @@
// 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_BROWSER_NAVIGATE_PARAMS_H_
#define CEF_LIBCEF_BROWSER_NAVIGATE_PARAMS_H_
#pragma once
#include <string>
#include "content/public/browser/global_request_id.h"
#include "content/public/common/page_transition_types.h"
#include "content/public/common/referrer.h"
#include "googleurl/src/gurl.h"
#include "net/base/upload_data.h"
#include "webkit/glue/window_open_disposition.h"
// Parameters that tell CefBrowserHostImpl::Navigate() what to do.
struct CefNavigateParams {
CefNavigateParams(const GURL& a_url,
content::PageTransition a_transition);
~CefNavigateParams();
// The following parameters are sent to the renderer via CefMsg_LoadRequest.
// ---------------------------------------------------------------------------
// Request method.
std::string method;
// The URL/referrer to be loaded.
GURL url;
content::Referrer referrer;
// The frame that the request should be loaded in or -1 to use the main frame.
int64 frame_id;
// Usually the URL of the document in the top-level window, which may be
// checked by the third-party cookie blocking policy. Leaving it empty may
// lead to undesired cookie blocking. Third-party cookie blocking can be
// bypassed by setting first_party_for_cookies = url, but this should ideally
// only be done if there really is no way to determine the correct value.
GURL first_party_for_cookies;
// Additional HTTP request headers.
std::string headers;
// net::URLRequest load flags (0 by default).
int load_flags;
// Upload data (may be NULL).
scoped_refptr<net::UploadData> upload_data;
// The following parameters are used to define browser behavior when servicing
// the navigation request.
// ---------------------------------------------------------------------------
// The disposition requested by the navigation source. Default is CURRENT_TAB.
WindowOpenDisposition disposition;
// The transition type of the navigation.
content::PageTransition transition;
// Whether this navigation was initiated by the renderer process.
bool is_renderer_initiated;
// If non-empty, the new tab contents encoding is overriden by this value.
std::string override_encoding;
// If false then the navigation was not initiated by a user gesture. Default
// is true.
bool user_gesture;
// Refers to a navigation that was parked in the browser in order to be
// transferred to another RVH. Only used in case of a redirection of a request
// to a different site that created a new RVH.
content::GlobalRequestID transferred_global_request_id;
private:
CefNavigateParams();
};
#endif // CEF_LIBCEF_BROWSER_NAVIGATE_PARAMS_H_

View File

@@ -0,0 +1,254 @@
// Copyright (c) 2011 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/browser/origin_whitelist_impl.h"
#include <string>
#include <list>
#include "include/cef_origin_whitelist.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_messages.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "content/public/browser/render_process_host.h"
#include "googleurl/src/gurl.h"
namespace {
// Class that manages cross-origin whitelist registrations.
class CefOriginWhitelistManager {
public:
CefOriginWhitelistManager() {}
// Retrieve the singleton instance.
static CefOriginWhitelistManager* GetInstance();
bool AddOriginEntry(const std::string& source_origin,
const std::string& target_protocol,
const std::string& target_domain,
bool allow_target_subdomains) {
CEF_REQUIRE_UIT();
OriginInfo info;
info.source_origin = source_origin;
info.target_protocol = target_protocol;
info.target_domain = target_domain;
info.allow_target_subdomains = allow_target_subdomains;
// Verify that the origin entry doesn't already exist.
OriginList::const_iterator it = origin_list_.begin();
for (; it != origin_list_.end(); ++it) {
if (it->Equals(info))
return false;
}
origin_list_.push_back(info);
SendModifyCrossOriginWhitelistEntry(true, source_origin, target_protocol,
target_domain, allow_target_subdomains);
return true;
}
bool RemoveOriginEntry(const std::string& source_origin,
const std::string& target_protocol,
const std::string& target_domain,
bool allow_target_subdomains) {
CEF_REQUIRE_UIT();
OriginInfo info;
info.source_origin = source_origin;
info.target_protocol = target_protocol;
info.target_domain = target_domain;
info.allow_target_subdomains = allow_target_subdomains;
bool found = false;
OriginList::iterator it = origin_list_.begin();
for (; it != origin_list_.end(); ++it) {
if (it->Equals(info)) {
origin_list_.erase(it);
found = true;
break;
}
}
if (!found)
return false;
SendModifyCrossOriginWhitelistEntry(false, source_origin, target_protocol,
target_domain, allow_target_subdomains);
return true;
}
void ClearOrigins() {
CEF_REQUIRE_UIT();
origin_list_.clear();
SendClearCrossOriginWhitelist();
}
// Send all existing cross-origin registrations to the specified host.
void RegisterOriginsWithHost(content::RenderProcessHost* host) {
CEF_REQUIRE_UIT();
if (origin_list_.empty())
return;
OriginList::const_iterator it = origin_list_.begin();
for (; it != origin_list_.end(); ++it) {
host->Send(
new CefProcessMsg_ModifyCrossOriginWhitelistEntry(
true, it->source_origin, it->target_protocol, it->target_domain,
it->allow_target_subdomains));
}
}
private:
// Send the modify cross-origin whitelist entry message to all currently
// existing hosts.
void SendModifyCrossOriginWhitelistEntry(bool add,
const std::string& source_origin,
const std::string& target_protocol,
const std::string& target_domain,
bool allow_target_subdomains) {
CEF_REQUIRE_UIT();
content::RenderProcessHost::iterator i(
content::RenderProcessHost::AllHostsIterator());
for (; !i.IsAtEnd(); i.Advance()) {
i.GetCurrentValue()->Send(
new CefProcessMsg_ModifyCrossOriginWhitelistEntry(
add, source_origin, target_protocol, target_domain,
allow_target_subdomains));
}
}
// Send the clear cross-origin whitelists message to all currently existing
// hosts.
void SendClearCrossOriginWhitelist() {
CEF_REQUIRE_UIT();
content::RenderProcessHost::iterator i(
content::RenderProcessHost::AllHostsIterator());
for (; !i.IsAtEnd(); i.Advance()) {
i.GetCurrentValue()->Send(new CefProcessMsg_ClearCrossOriginWhitelist);
}
}
struct OriginInfo {
std::string source_origin;
std::string target_protocol;
std::string target_domain;
bool allow_target_subdomains;
bool Equals(const OriginInfo& info) const {
return (source_origin == info.source_origin &&
target_protocol == info.target_protocol &&
target_domain == info.target_domain &&
allow_target_subdomains == info.allow_target_subdomains);
}
};
// List of registered origins.
typedef std::list<OriginInfo> OriginList;
OriginList origin_list_;
DISALLOW_EVIL_CONSTRUCTORS(CefOriginWhitelistManager);
};
base::LazyInstance<CefOriginWhitelistManager> g_manager =
LAZY_INSTANCE_INITIALIZER;
CefOriginWhitelistManager* CefOriginWhitelistManager::GetInstance() {
return g_manager.Pointer();
}
} // namespace
bool CefAddCrossOriginWhitelistEntry(const CefString& source_origin,
const CefString& target_protocol,
const CefString& target_domain,
bool allow_target_subdomains) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED();
return false;
}
std::string source_url = source_origin;
GURL gurl = GURL(source_url);
if (gurl.is_empty() || !gurl.is_valid()) {
NOTREACHED() << "Invalid source_origin URL: " << source_url;
return false;
}
if (CEF_CURRENTLY_ON_UIT()) {
return CefOriginWhitelistManager::GetInstance()->AddOriginEntry(
source_origin, target_protocol, target_domain, allow_target_subdomains);
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(base::IgnoreResult(&CefAddCrossOriginWhitelistEntry),
source_origin, target_protocol, target_domain,
allow_target_subdomains));
}
return true;
}
bool CefRemoveCrossOriginWhitelistEntry(const CefString& source_origin,
const CefString& target_protocol,
const CefString& target_domain,
bool allow_target_subdomains) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED();
return false;
}
std::string source_url = source_origin;
GURL gurl = GURL(source_url);
if (gurl.is_empty() || !gurl.is_valid()) {
NOTREACHED() << "Invalid source_origin URL: " << source_url;
return false;
}
if (CEF_CURRENTLY_ON_UIT()) {
return CefOriginWhitelistManager::GetInstance()->RemoveOriginEntry(
source_origin, target_protocol, target_domain, allow_target_subdomains);
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(base::IgnoreResult(&CefRemoveCrossOriginWhitelistEntry),
source_origin, target_protocol, target_domain,
allow_target_subdomains));
}
return true;
}
bool CefClearCrossOriginWhitelist() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED();
return false;
}
if (CEF_CURRENTLY_ON_UIT()) {
CefOriginWhitelistManager::GetInstance()->ClearOrigins();
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(base::IgnoreResult(&CefClearCrossOriginWhitelist)));
}
return true;
}
void RegisterCrossOriginWhitelistEntriesWithHost(
content::RenderProcessHost* host) {
CEF_REQUIRE_UIT();
CefOriginWhitelistManager::GetInstance()->RegisterOriginsWithHost(host);
}

View File

@@ -0,0 +1,17 @@
// 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_BROWSER_ORIGIN_WHITELIST_IMPL_H_
#define CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_
namespace content {
class RenderProcessHost;
}
// Called when a new RenderProcessHost is created to send existing cross-origin
// whitelist entry information.
void RegisterCrossOriginWhitelistEntriesWithHost(
content::RenderProcessHost* host);
#endif // CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_

View File

@@ -0,0 +1,25 @@
// 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/browser/resource_context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
CefResourceContext::CefResourceContext(
CefURLRequestContextGetter* getter)
: getter_(getter) {
}
CefResourceContext::~CefResourceContext() {
}
net::HostResolver* CefResourceContext::GetHostResolver() {
CEF_REQUIRE_IOT();
return getter_->host_resolver();
}
net::URLRequestContext* CefResourceContext::GetRequestContext() {
CEF_REQUIRE_IOT();
return getter_->GetURLRequestContext();
}

View File

@@ -0,0 +1,31 @@
// 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_BROWSER_RESOURCE_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_RESOURCE_CONTEXT_H_
#pragma once
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/resource_context.h"
class CefURLRequestContextGetter;
class CefResourceContext : public content::ResourceContext {
public:
explicit CefResourceContext(CefURLRequestContextGetter* getter);
virtual ~CefResourceContext();
private:
// ResourceContext methods.
virtual net::HostResolver* GetHostResolver() OVERRIDE;
virtual net::URLRequestContext* GetRequestContext() OVERRIDE;
scoped_refptr<CefURLRequestContextGetter> getter_;
DISALLOW_COPY_AND_ASSIGN(CefResourceContext);
};
#endif // CEF_LIBCEF_BROWSER_RESOURCE_CONTEXT_H_

View File

@@ -0,0 +1,480 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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/browser/resource_request_job.h"
#include <map>
#include <vector>
#include "include/cef_callback.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "base/logging.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
using net::URLRequestStatus;
// Client callback for asynchronous response continuation.
class CefResourceRequestJobCallback : public CefCallback {
public:
enum Type {
HEADERS_AVAILABLE,
BYTES_AVAILABLE,
};
explicit CefResourceRequestJobCallback(CefResourceRequestJob* job, Type type)
: job_(job),
type_(type),
dest_(NULL),
dest_size_(0) {}
virtual void Continue() OVERRIDE {
if (CEF_CURRENTLY_ON_IOT()) {
// Currently on IO thread.
// Return early if the callback has already been detached.
if (!job_)
return;
if (type_ == HEADERS_AVAILABLE) {
// Callback for headers available.
if (!job_->has_response_started()) {
// Send header information.
job_->SendHeaders();
}
// This type of callback only ever needs to be called once.
Detach();
} else if (type_ == BYTES_AVAILABLE) {
// Callback for bytes available.
if (job_->has_response_started() &&
job_->GetStatus().is_io_pending()) {
// Read the bytes. They should be available but, if not, wait again.
int bytes_read = 0;
if (job_->ReadRawData(dest_, dest_size_, &bytes_read)) {
if (bytes_read > 0) {
// Clear the IO_PENDING status.
job_->SetStatus(URLRequestStatus());
// Notify about the available bytes.
job_->NotifyReadComplete(bytes_read);
dest_ = NULL;
dest_size_ = 0;
}
} else {
// All done.
job_->NotifyDone(URLRequestStatus());
Detach();
}
}
}
} else {
// Execute this method on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceRequestJobCallback::Continue, this));
}
}
virtual void Cancel() OVERRIDE {
if (CEF_CURRENTLY_ON_IOT()) {
// Currently on IO thread.
if (job_)
job_->Kill();
} else {
// Execute this method on the IO thread.
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefResourceRequestJobCallback::Cancel, this));
}
}
void Detach() {
CEF_REQUIRE_IOT();
job_ = NULL;
}
void SetDestination(net::IOBuffer* dest, int dest_size) {
CEF_REQUIRE_IOT();
dest_ = dest;
dest_size_ = dest_size;
}
private:
CefResourceRequestJob* job_;
Type type_;
net::IOBuffer* dest_;
int dest_size_;
IMPLEMENT_REFCOUNTING(Callback);
};
CefResourceRequestJob::CefResourceRequestJob(
net::URLRequest* request,
CefRefPtr<CefResourceHandler> handler)
: net::URLRequestJob(request),
handler_(handler),
remaining_bytes_(0),
response_cookies_save_index_(0),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
}
CefResourceRequestJob::~CefResourceRequestJob() {
}
void CefResourceRequestJob::Start() {
CEF_REQUIRE_IOT();
cef_request_ = CefRequest::CreateRequest();
// Populate the request data.
static_cast<CefRequestImpl*>(cef_request_.get())->Set(request_);
// Add default headers if not already specified.
const net::URLRequestContext* context = request_->context();
if (context) {
CefRequest::HeaderMap::const_iterator it;
CefRequest::HeaderMap headerMap;
cef_request_->GetHeaderMap(headerMap);
bool changed = false;
if (!context->accept_language().empty()) {
it = headerMap.find(net::HttpRequestHeaders::kAcceptLanguage);
if (it == headerMap.end()) {
headerMap.insert(
std::make_pair(net::HttpRequestHeaders::kAcceptLanguage,
context->accept_language()));
}
changed = true;
}
if (!context->accept_charset().empty()) {
it = headerMap.find(net::HttpRequestHeaders::kAcceptCharset);
if (it == headerMap.end()) {
headerMap.insert(
std::make_pair(net::HttpRequestHeaders::kAcceptCharset,
context->accept_charset()));
}
changed = true;
}
it = headerMap.find(net::HttpRequestHeaders::kUserAgent);
if (it == headerMap.end()) {
headerMap.insert(
std::make_pair(net::HttpRequestHeaders::kUserAgent,
context->GetUserAgent(request_->url())));
changed = true;
}
if (changed)
cef_request_->SetHeaderMap(headerMap);
}
AddCookieHeaderAndStart();
}
void CefResourceRequestJob::Kill() {
CEF_REQUIRE_IOT();
// Notify the handler that the request has been canceled.
handler_->Cancel();
if (callback_) {
callback_->Detach();
callback_ = NULL;
}
net::URLRequestJob::Kill();
}
bool CefResourceRequestJob::ReadRawData(net::IOBuffer* dest, int dest_size,
int* bytes_read) {
CEF_REQUIRE_IOT();
DCHECK_NE(dest_size, 0);
DCHECK(bytes_read);
if (remaining_bytes_ == 0) {
// No more data to read.
*bytes_read = 0;
return true;
} else if (remaining_bytes_ > 0 && remaining_bytes_ < dest_size) {
// The handler knows the content size beforehand.
dest_size = static_cast<int>(remaining_bytes_);
}
if (!callback_.get()) {
// Create the bytes available callback that will be used until the request
// is completed.
callback_ = new CefResourceRequestJobCallback(this,
CefResourceRequestJobCallback::BYTES_AVAILABLE);
}
// Read response data from the handler.
bool rv = handler_->ReadResponse(dest->data(), dest_size, *bytes_read,
callback_.get());
if (!rv) {
// The handler has indicated completion of the request.
*bytes_read = 0;
return true;
} else if (*bytes_read == 0) {
if (!GetStatus().is_io_pending()) {
// Report our status as IO pending.
SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
callback_->SetDestination(dest, dest_size);
}
return false;
} else if (*bytes_read > dest_size) {
// Normalize the return value.
*bytes_read = dest_size;
}
if (remaining_bytes_ > 0)
remaining_bytes_ -= *bytes_read;
// Continue calling this method.
return true;
}
void CefResourceRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
CEF_REQUIRE_IOT();
info->headers = GetResponseHeaders();
}
bool CefResourceRequestJob::IsRedirectResponse(GURL* location,
int* http_status_code) {
CEF_REQUIRE_IOT();
if (redirect_url_.is_valid()) {
// Redirect to the new URL.
*http_status_code = 303;
location->Swap(&redirect_url_);
return true;
}
if (response_.get()) {
// Check for HTTP 302 or HTTP 303 redirect.
int status = response_->GetStatus();
if (status == 302 || status == 303) {
CefResponse::HeaderMap headerMap;
response_->GetHeaderMap(headerMap);
CefRequest::HeaderMap::iterator iter = headerMap.find("Location");
if (iter != headerMap.end()) {
GURL new_url = GURL(std::string(iter->second));
*http_status_code = status;
location->Swap(&new_url);
return true;
}
}
}
return false;
}
bool CefResourceRequestJob::GetMimeType(std::string* mime_type) const {
CEF_REQUIRE_IOT();
if (response_.get())
*mime_type = response_->GetMimeType();
return true;
}
void CefResourceRequestJob::SendHeaders() {
CEF_REQUIRE_IOT();
// Clear the headers available callback.
callback_ = NULL;
// We may have been orphaned...
if (!request())
return;
response_ = new CefResponseImpl();
remaining_bytes_ = 0;
CefString redirectUrl;
// Get header information from the handler.
handler_->GetResponseHeaders(response_, remaining_bytes_, redirectUrl);
if (!redirectUrl.empty()) {
std::string redirectUrlStr = redirectUrl;
redirect_url_ = GURL(redirectUrlStr);
}
if (remaining_bytes_ > 0)
set_expected_content_size(remaining_bytes_);
// Continue processing the request.
SaveCookiesAndNotifyHeadersComplete();
}
void CefResourceRequestJob::AddCookieHeaderAndStart() {
// No matter what, we want to report our status as IO pending since we will
// be notifying our consumer asynchronously via OnStartCompleted.
SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
// If the request was destroyed, then there is no more work to do.
if (!request_)
return;
net::CookieStore* cookie_store =
request_->context()->cookie_store();
if (cookie_store &&
!(request_->load_flags() & net::LOAD_DO_NOT_SEND_COOKIES)) {
net::CookieMonster* cookie_monster = cookie_store->GetCookieMonster();
if (cookie_monster) {
cookie_monster->GetAllCookiesForURLAsync(
request_->url(),
base::Bind(&CefResourceRequestJob::CheckCookiePolicyAndLoad,
weak_factory_.GetWeakPtr()));
} else {
DoLoadCookies();
}
} else {
DoStartTransaction();
}
}
void CefResourceRequestJob::DoLoadCookies() {
net::CookieOptions options;
options.set_include_httponly();
request_->context()->cookie_store()->GetCookiesWithInfoAsync(
request_->url(), options,
base::Bind(&CefResourceRequestJob::OnCookiesLoaded,
weak_factory_.GetWeakPtr()));
}
void CefResourceRequestJob::CheckCookiePolicyAndLoad(
const net::CookieList& cookie_list) {
if (CanGetCookies(cookie_list))
DoLoadCookies();
else
DoStartTransaction();
}
void CefResourceRequestJob::OnCookiesLoaded(
const std::string& cookie_line,
const std::vector<net::CookieStore::CookieInfo>& cookie_infos) {
if (!cookie_line.empty()) {
CefRequest::HeaderMap headerMap;
cef_request_->GetHeaderMap(headerMap);
headerMap.insert(
std::make_pair(net::HttpRequestHeaders::kCookie, cookie_line));
cef_request_->SetHeaderMap(headerMap);
}
DoStartTransaction();
}
void CefResourceRequestJob::DoStartTransaction() {
// We may have been canceled while retrieving cookies.
if (GetStatus().is_success()) {
StartTransaction();
} else {
NotifyCanceled();
}
}
void CefResourceRequestJob::StartTransaction() {
// Create the callback that will be used to notify when header information is
// available.
callback_ = new CefResourceRequestJobCallback(this,
CefResourceRequestJobCallback::HEADERS_AVAILABLE);
// Protect against deletion of this object.
base::WeakPtr<CefResourceRequestJob> weak_ptr(weak_factory_.GetWeakPtr());
// Handler can decide whether to process the request.
bool rv = handler_->ProcessRequest(cef_request_, callback_.get());
if (weak_ptr.get() && !rv) {
// Cancel the request.
NotifyCanceled();
}
}
net::HttpResponseHeaders* CefResourceRequestJob::GetResponseHeaders() {
DCHECK(response_);
if (!response_headers_.get()) {
CefResponseImpl* responseImpl =
static_cast<CefResponseImpl*>(response_.get());
response_headers_ = responseImpl->GetResponseHeaders();
}
return response_headers_;
}
void CefResourceRequestJob::SaveCookiesAndNotifyHeadersComplete() {
if (request_->load_flags() & net::LOAD_DO_NOT_SAVE_COOKIES) {
SetStatus(URLRequestStatus()); // Clear the IO_PENDING status
NotifyHeadersComplete();
return;
}
response_cookies_.clear();
response_cookies_save_index_ = 0;
FetchResponseCookies(&response_cookies_);
// Now, loop over the response cookies, and attempt to persist each.
SaveNextCookie();
}
void CefResourceRequestJob::SaveNextCookie() {
if (response_cookies_save_index_ == response_cookies_.size()) {
response_cookies_.clear();
response_cookies_save_index_ = 0;
SetStatus(URLRequestStatus()); // Clear the IO_PENDING status
NotifyHeadersComplete();
return;
}
// No matter what, we want to report our status as IO pending since we will
// be notifying our consumer asynchronously via OnStartCompleted.
SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
net::CookieOptions options;
options.set_include_httponly();
if (CanSetCookie(
response_cookies_[response_cookies_save_index_], &options)) {
request_->context()->cookie_store()->SetCookieWithOptionsAsync(
request_->url(), response_cookies_[response_cookies_save_index_],
options, base::Bind(&CefResourceRequestJob::OnCookieSaved,
weak_factory_.GetWeakPtr()));
return;
}
CookieHandled();
}
void CefResourceRequestJob::OnCookieSaved(bool cookie_status) {
CookieHandled();
}
void CefResourceRequestJob::CookieHandled() {
response_cookies_save_index_++;
// We may have been canceled within OnSetCookie.
if (GetStatus().is_success()) {
SaveNextCookie();
} else {
NotifyCanceled();
}
}
void CefResourceRequestJob::FetchResponseCookies(
std::vector<std::string>* cookies) {
const std::string name = "Set-Cookie";
std::string value;
void* iter = NULL;
net::HttpResponseHeaders* headers = GetResponseHeaders();
while (headers->EnumerateHeader(&iter, name, &value)) {
if (!value.empty())
cookies->push_back(value);
}
}

View File

@@ -0,0 +1,78 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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_BROWSER_RESOURCE_REQUEST_JOB_H_
#define CEF_LIBCEF_BROWSER_RESOURCE_REQUEST_JOB_H_
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_request_handler.h"
#include "net/cookies/cookie_monster.h"
#include "net/url_request/url_request_job.h"
namespace net {
class HttpResponseHeaders;
class URLRequest;
}
class CefResourceRequestJobCallback;
class CefResourceRequestJob : public net::URLRequestJob {
public:
CefResourceRequestJob(net::URLRequest* request,
CefRefPtr<CefResourceHandler> handler);
virtual ~CefResourceRequestJob();
private:
// net::URLRequestJob methods.
virtual void Start() OVERRIDE;
virtual void Kill() OVERRIDE;
virtual bool ReadRawData(net::IOBuffer* dest, int dest_size, int* bytes_read)
OVERRIDE;
virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
virtual bool IsRedirectResponse(GURL* location, int* http_status_code)
OVERRIDE;
virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
void SendHeaders();
// Used for sending cookies with the request.
void AddCookieHeaderAndStart();
void DoLoadCookies();
void CheckCookiePolicyAndLoad(const net::CookieList& cookie_list);
void OnCookiesLoaded(
const std::string& cookie_line,
const std::vector<net::CookieStore::CookieInfo>& cookie_infos);
void DoStartTransaction();
void StartTransaction();
// Used for saving cookies returned as part of the response.
net::HttpResponseHeaders* GetResponseHeaders();
void SaveCookiesAndNotifyHeadersComplete();
void SaveNextCookie();
void OnCookieSaved(bool cookie_status);
void CookieHandled();
void FetchResponseCookies(std::vector<std::string>* cookies);
CefRefPtr<CefResourceHandler> handler_;
CefRefPtr<CefResponse> response_;
GURL redirect_url_;
int64 remaining_bytes_;
CefRefPtr<CefRequest> cef_request_;
CefRefPtr<CefResourceRequestJobCallback> callback_;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
std::vector<std::string> response_cookies_;
size_t response_cookies_save_index_;
base::WeakPtrFactory<CefResourceRequestJob> weak_factory_;
friend class CefResourceRequestJobCallback;
DISALLOW_COPY_AND_ASSIGN(CefResourceRequestJob);
};
#endif // CEF_LIBCEF_BROWSER_RESOURCE_REQUEST_JOB_H_

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/cef_resources.h" type="rc_header">
<emit emit_type='prepend'></emit>
</output>
<output filename="cef_resources.pak" type="data_package" />
<output filename="cef_resources.rc" type="rc_all" />
</outputs>
<translations />
<release seq="1">
<includes>
<include name="IDR_CEF_DEVTOOLS_DISCOVERY_PAGE" file="devtools_discovery_page.html" type="BINDATA" />
</includes>
</release>
</grit>

View File

@@ -0,0 +1,54 @@
<html>
<head>
<title>CEF remote debugging</title>
<style>
</style>
<script>
function onLoad() {
var tabs_list_request = new XMLHttpRequest();
tabs_list_request.open("GET", "/json" + new Date().getTime(), true);
tabs_list_request.onreadystatechange = onReady;
tabs_list_request.send();
}
function onReady() {
if(this.readyState == 4 && this.status == 200) {
if(this.response != null)
var responseJSON = JSON.parse(this.response);
for (var i = 0; i < responseJSON.length; ++i)
appendItem(responseJSON[i]);
}
}
function appendItem(item_object) {
var frontend_ref;
if (item_object.devtoolsFrontendUrl) {
frontend_ref = document.createElement("a");
frontend_ref.href = item_object.devtoolsFrontendUrl;
frontend_ref.title = item_object.title;
} else {
frontend_ref = document.createElement("div");
frontend_ref.title = "The tab already has active debugging session";
}
var text = document.createElement("div");
if (item_object.title)
text.innerText = item_object.title;
else
text.innerText = "(untitled tab)";
text.style.cssText = "background-image:url(" + item_object.faviconUrl + ")";
frontend_ref.appendChild(text);
var item = document.createElement("p");
item.appendChild(frontend_ref);
document.getElementById("items").appendChild(item);
}
</script>
</head>
<body onload='onLoad()'>
<div id='caption'>Inspectable WebContents</div>
<div id='items'></div>
</body>
</html>

View File

@@ -0,0 +1,447 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2009 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/browser/scheme_impl.h"
#include <map>
#include "include/cef_browser.h"
#include "include/cef_scheme.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/context.h"
#include "libcef/browser/resource_request_job.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/request_impl.h"
#include "libcef/common/response_impl.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/render_process_host.h"
#include "googleurl/src/url_util.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/upload_data.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_about_job.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_data_job.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_file_job.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_ftp_job.h"
#include "net/url_request/url_request_http_job.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
using net::URLRequestStatus;
namespace {
bool IsStandardScheme(const std::string& scheme) {
url_parse::Component scheme_comp(0, scheme.length());
return url_util::IsStandard(scheme.c_str(), scheme_comp);
}
void RegisterStandardScheme(const std::string& scheme) {
CEF_REQUIRE_UIT();
url_parse::Component scheme_comp(0, scheme.length());
if (!url_util::IsStandard(scheme.c_str(), scheme_comp))
url_util::AddStandardScheme(scheme.c_str());
}
// Copied from net/url_request/url_request_job_manager.cc.
struct SchemeToFactory {
const char* scheme;
net::URLRequest::ProtocolFactory* factory;
};
static const SchemeToFactory kBuiltinFactories[] = {
{ "http", net::URLRequestHttpJob::Factory },
{ "https", net::URLRequestHttpJob::Factory },
{ "file", net::URLRequestFileJob::Factory },
{ "ftp", net::URLRequestFtpJob::Factory },
{ "about", net::URLRequestAboutJob::Factory },
{ "data", net::URLRequestDataJob::Factory },
};
bool IsBuiltinScheme(const std::string& scheme) {
for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i)
if (LowerCaseEqualsASCII(scheme, kBuiltinFactories[i].scheme))
return true;
return false;
}
net::URLRequestJob* GetBuiltinSchemeRequestJob(net::URLRequest* request,
const std::string& scheme) {
// See if the request should be handled by a built-in protocol factory.
for (size_t i = 0; i < arraysize(kBuiltinFactories); ++i) {
if (scheme == kBuiltinFactories[i].scheme) {
net::URLRequestJob* job = (kBuiltinFactories[i].factory)(request, scheme);
DCHECK(job); // The built-in factories are not expected to fail!
return job;
}
}
return NULL;
}
std::string ToLower(const std::string& str) {
std::string str_lower = str;
std::transform(str_lower.begin(), str_lower.end(), str_lower.begin(),
towlower);
return str;
}
// Class that manages the CefSchemeHandlerFactory instances.
class CefUrlRequestManager {
protected:
// Class used for creating URLRequestJob instances. The lifespan of this
// object is managed by URLRequestJobFactory.
class ProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
explicit ProtocolHandler(const std::string& scheme)
: scheme_(scheme) {}
// From net::URLRequestJobFactory::ProtocolHandler
virtual net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request) const OVERRIDE {
CEF_REQUIRE_IOT();
return CefUrlRequestManager::GetInstance()->GetRequestJob(request,
scheme_);
}
private:
std::string scheme_;
};
public:
CefUrlRequestManager() {}
// Retrieve the singleton instance.
static CefUrlRequestManager* GetInstance();
net::URLRequestJobFactory* GetJobFactory() {
return const_cast<net::URLRequestJobFactory*>(
static_cast<CefURLRequestContextGetter*>(
_Context->browser_context()->GetRequestContext())->
GetURLRequestContext()->job_factory());
}
bool AddFactory(const std::string& scheme,
const std::string& domain,
CefRefPtr<CefSchemeHandlerFactory> factory) {
if (!factory.get()) {
RemoveFactory(scheme, domain);
return true;
}
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
domain_lower.clear();
handler_map_[make_pair(scheme_lower, domain_lower)] = factory;
net::URLRequestJobFactory* job_factory = GetJobFactory();
job_factory->SetProtocolHandler(scheme_lower,
new ProtocolHandler(scheme_lower));
return true;
}
void RemoveFactory(const std::string& scheme,
const std::string& domain) {
CEF_REQUIRE_IOT();
std::string scheme_lower = ToLower(scheme);
std::string domain_lower = ToLower(domain);
// Hostname is only supported for standard schemes.
if (!IsStandardScheme(scheme_lower))
domain_lower.clear();
HandlerMap::iterator iter =
handler_map_.find(make_pair(scheme_lower, domain_lower));
if (iter != handler_map_.end())
handler_map_.erase(iter);
}
// Clear all the existing URL handlers and unregister the ProtocolFactory.
void ClearFactories() {
CEF_REQUIRE_IOT();
net::URLRequestJobFactory* job_factory = GetJobFactory();
// Unregister with the ProtocolFactory.
std::set<std::string> schemes;
for (HandlerMap::const_iterator i = handler_map_.begin();
i != handler_map_.end(); ++i) {
schemes.insert(i->first.first);
}
for (std::set<std::string>::const_iterator scheme = schemes.begin();
scheme != schemes.end(); ++scheme) {
job_factory->SetProtocolHandler(*scheme, NULL);
}
handler_map_.clear();
}
// Check if a scheme has already been registered.
bool HasRegisteredScheme(const std::string& scheme) {
std::string scheme_lower = ToLower(scheme);
// Don't register builtin schemes.
if (IsBuiltinScheme(scheme_lower))
return true;
scheme_map_lock_.Acquire();
bool registered = (scheme_map_.find(scheme_lower) != scheme_map_.end());
scheme_map_lock_.Release();
return registered;
}
// Register a scheme.
bool RegisterScheme(const std::string& scheme,
bool is_standard,
bool is_local,
bool is_display_isolated) {
if (HasRegisteredScheme(scheme)) {
NOTREACHED() << "Scheme already registered: " << scheme;
return false;
}
std::string scheme_lower = ToLower(scheme);
SchemeInfo info;
info.is_standard = is_standard;
info.is_local = is_local;
info.is_display_isolated = is_display_isolated;
scheme_map_lock_.Acquire();
scheme_map_.insert(std::make_pair(scheme_lower, info));
scheme_map_lock_.Release();
if (is_standard && !content::RenderProcessHost::run_renderer_in_process()) {
// When running in multi-process mode the scheme must be registered with
// url_util in the browser process as well.
RegisterStandardScheme(scheme_lower);
}
SendRegisterScheme(scheme_lower, is_standard, is_local,
is_display_isolated);
return true;
}
// Send all existing scheme registrations to the specified host.
void RegisterSchemesWithHost(content::RenderProcessHost* host) {
base::AutoLock lock_scope(scheme_map_lock_);
if (scheme_map_.empty())
return;
SchemeMap::const_iterator it = scheme_map_.begin();
for (; it != scheme_map_.end(); ++it) {
host->Send(
new CefProcessMsg_RegisterScheme(it->first, it->second.is_standard,
it->second.is_local,
it->second.is_display_isolated));
}
}
private:
// Retrieve the matching handler factory, if any. |scheme| will already be in
// lower case.
CefRefPtr<CefSchemeHandlerFactory> GetHandlerFactory(
net::URLRequest* request, const std::string& scheme) {
CefRefPtr<CefSchemeHandlerFactory> factory;
if (request->url().is_valid() && IsStandardScheme(scheme)) {
// Check for a match with a domain first.
const std::string& domain = request->url().host();
HandlerMap::iterator i = handler_map_.find(make_pair(scheme, domain));
if (i != handler_map_.end())
factory = i->second;
}
if (!factory.get()) {
// Check for a match with no specified domain.
HandlerMap::iterator i =
handler_map_.find(make_pair(scheme, std::string()));
if (i != handler_map_.end())
factory = i->second;
}
return factory;
}
// Create the job that will handle the request. |scheme| will already be in
// lower case.
net::URLRequestJob* GetRequestJob(net::URLRequest* request,
const std::string& scheme) {
net::URLRequestJob* job = NULL;
CefRefPtr<CefSchemeHandlerFactory> factory =
GetHandlerFactory(request, scheme);
if (factory) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
// Populate the request data.
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
requestPtr->Set(request);
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
// Call the handler factory to create the handler for the request.
CefRefPtr<CefResourceHandler> handler =
factory->Create(browser.get(), frame, scheme, requestPtr.get());
if (handler.get())
job = new CefResourceRequestJob(request, handler);
}
}
if (!job && IsBuiltinScheme(scheme)) {
// Give the built-in scheme handler a chance to handle the request.
job = GetBuiltinSchemeRequestJob(request, scheme);
}
#ifndef NDEBUG
if (job)
DLOG(INFO) << "CefUrlRequestManager hit for " << request->url().spec();
#endif
return job;
}
// Send the register scheme message to all currently existing hosts.
void SendRegisterScheme(const std::string& scheme_name,
bool is_standard,
bool is_local,
bool is_display_isolated) {
CEF_REQUIRE_UIT();
content::RenderProcessHost::iterator i(
content::RenderProcessHost::AllHostsIterator());
for (; !i.IsAtEnd(); i.Advance()) {
i.GetCurrentValue()->Send(
new CefProcessMsg_RegisterScheme(scheme_name, is_standard, is_local,
is_display_isolated));
}
}
// Map (scheme, domain) to factories. This map will only be accessed on the IO
// thread.
typedef std::map<std::pair<std::string, std::string>,
CefRefPtr<CefSchemeHandlerFactory> > HandlerMap;
HandlerMap handler_map_;
struct SchemeInfo {
bool is_standard;
bool is_local;
bool is_display_isolated;
};
// Map of registered schemes. Access to this map must be protected by the
// associated lock.
typedef std::map<std::string, SchemeInfo> SchemeMap;
SchemeMap scheme_map_;
base::Lock scheme_map_lock_;
DISALLOW_EVIL_CONSTRUCTORS(CefUrlRequestManager);
};
base::LazyInstance<CefUrlRequestManager> g_manager = LAZY_INSTANCE_INITIALIZER;
CefUrlRequestManager* CefUrlRequestManager::GetInstance() {
return g_manager.Pointer();
}
} // namespace
bool CefRegisterCustomScheme(const CefString& scheme_name,
bool is_standard,
bool is_local,
bool is_display_isolated) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
}
if (CEF_CURRENTLY_ON(CEF_UIT)) {
// Must be executed on the UI thread.
return CefUrlRequestManager::GetInstance()->RegisterScheme(scheme_name,
is_standard, is_local, is_display_isolated);
} else {
// Verify that the scheme has not already been registered.
if (CefUrlRequestManager::GetInstance()->HasRegisteredScheme(scheme_name)) {
NOTREACHED() << "Scheme already registered: " << scheme_name;
return false;
}
CEF_POST_TASK(CEF_UIT,
base::Bind(base::IgnoreResult(&CefRegisterCustomScheme), scheme_name,
is_standard, is_local, is_display_isolated));
return true;
}
}
bool CefRegisterSchemeHandlerFactory(
const CefString& scheme_name,
const CefString& domain_name,
CefRefPtr<CefSchemeHandlerFactory> factory) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
}
if (CEF_CURRENTLY_ON(CEF_IOT)) {
return CefUrlRequestManager::GetInstance()->AddFactory(scheme_name,
domain_name,
factory);
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefRegisterSchemeHandlerFactory),
scheme_name, domain_name, factory));
return true;
}
}
bool CefClearSchemeHandlerFactories() {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED() << "context not valid";
return false;
}
if (CEF_CURRENTLY_ON(CEF_IOT)) {
CefUrlRequestManager::GetInstance()->ClearFactories();
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(base::IgnoreResult(&CefClearSchemeHandlerFactories)));
}
return true;
}
void RegisterSchemesWithHost(content::RenderProcessHost* host) {
CEF_REQUIRE_UIT();
CefUrlRequestManager::GetInstance()->RegisterSchemesWithHost(host);
}

View File

@@ -0,0 +1,16 @@
// 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_BROWSER_SCHEME_IMPL_H_
#define CEF_LIBCEF_BROWSER_SCHEME_IMPL_H_
namespace content {
class RenderProcessHost;
}
// Called when a new RenderProcessHost is created to send existing scheme
// registration information.
void RegisterSchemesWithHost(content::RenderProcessHost* host);
#endif // CEF_LIBCEF_BROWSER_SCHEME_IMPL_H_

View File

@@ -0,0 +1,10 @@
// 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 "chrome/browser/diagnostics/sqlite_diagnostics.h"
// Used by SQLitePersistentCookieStore
sql::ErrorDelegate* GetErrorHandlerForCookieDb() {
return NULL;
}

View File

@@ -0,0 +1,309 @@
// Copyright (c) 2008 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/browser/stream_impl.h"
#include <stdlib.h>
#include "base/logging.h"
// Static functions
CefRefPtr<CefStreamReader> CefStreamReader::CreateForFile(
const CefString& fileName) {
CefRefPtr<CefStreamReader> reader;
std::string fileNameStr = fileName;
FILE* file = fopen(fileNameStr.c_str(), "rb");
if (file)
reader = new CefFileReader(file, true);
return reader;
}
CefRefPtr<CefStreamReader> CefStreamReader::CreateForData(void* data,
size_t size) {
DCHECK(data != NULL);
DCHECK(size > 0); // NOLINT(readability/check)
CefRefPtr<CefStreamReader> reader;
if (data && size > 0)
reader = new CefBytesReader(data, size, true);
return reader;
}
CefRefPtr<CefStreamReader> CefStreamReader::CreateForHandler(
CefRefPtr<CefReadHandler> handler) {
DCHECK(handler.get());
CefRefPtr<CefStreamReader> reader;
if (handler.get())
reader = new CefHandlerReader(handler);
return reader;
}
CefRefPtr<CefStreamWriter> CefStreamWriter::CreateForFile(
const CefString& fileName) {
DCHECK(!fileName.empty());
CefRefPtr<CefStreamWriter> writer;
std::string fileNameStr = fileName;
FILE* file = fopen(fileNameStr.c_str(), "wb");
if (file)
writer = new CefFileWriter(file, true);
return writer;
}
CefRefPtr<CefStreamWriter> CefStreamWriter::CreateForHandler(
CefRefPtr<CefWriteHandler> handler) {
DCHECK(handler.get());
CefRefPtr<CefStreamWriter> writer;
if (handler.get())
writer = new CefHandlerWriter(handler);
return writer;
}
// CefFileReader
CefFileReader::CefFileReader(FILE* file, bool close)
: close_(close), file_(file) {
}
CefFileReader::~CefFileReader() {
AutoLock lock_scope(this);
if (close_)
fclose(file_);
}
size_t CefFileReader::Read(void* ptr, size_t size, size_t n) {
AutoLock lock_scope(this);
return fread(ptr, size, n, file_);
}
int CefFileReader::Seek(int64 offset, int whence) {
AutoLock lock_scope(this);
#if defined(OS_WIN)
return _fseeki64(file_, offset, whence);
#else
return fseek(file_, offset, whence);
#endif
}
int64 CefFileReader::Tell() {
AutoLock lock_scope(this);
#if defined(OS_WIN)
return _ftelli64(file_);
#else
return ftell(file_);
#endif
}
int CefFileReader::Eof() {
AutoLock lock_scope(this);
return feof(file_);
}
// CefFileWriter
CefFileWriter::CefFileWriter(FILE* file, bool close)
: file_(file),
close_(close) {
}
CefFileWriter::~CefFileWriter() {
AutoLock lock_scope(this);
if (close_)
fclose(file_);
}
size_t CefFileWriter::Write(const void* ptr, size_t size, size_t n) {
AutoLock lock_scope(this);
return (size_t)fwrite(ptr, size, n, file_);
}
int CefFileWriter::Seek(int64 offset, int whence) {
AutoLock lock_scope(this);
return fseek(file_, offset, whence);
}
int64 CefFileWriter::Tell() {
AutoLock lock_scope(this);
return ftell(file_);
}
int CefFileWriter::Flush() {
AutoLock lock_scope(this);
return fflush(file_);
}
// CefBytesReader
CefBytesReader::CefBytesReader(void* data, int64 datasize, bool copy)
: data_(NULL),
datasize_(0),
copy_(false),
offset_(0) {
SetData(data, datasize, copy);
}
CefBytesReader::~CefBytesReader() {
SetData(NULL, 0, false);
}
size_t CefBytesReader::Read(void* ptr, size_t size, size_t n) {
AutoLock lock_scope(this);
size_t s = (datasize_ - offset_) / size;
size_t ret = (n < s ? n : s);
memcpy(ptr, (reinterpret_cast<char*>(data_)) + offset_, ret * size);
offset_ += ret * size;
return ret;
}
int CefBytesReader::Seek(int64 offset, int whence) {
int rv = -1L;
AutoLock lock_scope(this);
switch (whence) {
case SEEK_CUR:
if (offset_ + offset > datasize_ || offset_ + offset < 0)
break;
offset_ += offset;
rv = 0;
break;
case SEEK_END: {
int64 offset_abs = abs(offset);
if (offset_abs > datasize_)
break;
offset_ = datasize_ - offset_abs;
rv = 0;
break;
}
case SEEK_SET:
if (offset > datasize_ || offset < 0)
break;
offset_ = offset;
rv = 0;
break;
}
return rv;
}
int64 CefBytesReader::Tell() {
AutoLock lock_scope(this);
return offset_;
}
int CefBytesReader::Eof() {
AutoLock lock_scope(this);
return (offset_ >= datasize_);
}
void CefBytesReader::SetData(void* data, int64 datasize, bool copy) {
AutoLock lock_scope(this);
if (copy_)
free(data_);
copy_ = copy;
offset_ = 0;
datasize_ = datasize;
if (copy) {
data_ = malloc(datasize);
DCHECK(data_ != NULL);
if (data_)
memcpy(data_, data, datasize);
} else {
data_ = data;
}
}
// CefBytesWriter
CefBytesWriter::CefBytesWriter(size_t grow)
: grow_(grow),
datasize_(grow),
offset_(0) {
DCHECK(grow > 0); // NOLINT(readability/check)
data_ = malloc(grow);
DCHECK(data_ != NULL);
}
CefBytesWriter::~CefBytesWriter() {
AutoLock lock_scope(this);
if (data_)
free(data_);
}
size_t CefBytesWriter::Write(const void* ptr, size_t size, size_t n) {
AutoLock lock_scope(this);
size_t rv;
if (offset_ + static_cast<int64>(size * n) >= datasize_ &&
Grow(size * n) == 0) {
rv = 0;
} else {
memcpy(reinterpret_cast<char*>(data_) + offset_, ptr, size * n);
offset_ += size * n;
rv = n;
}
return rv;
}
int CefBytesWriter::Seek(int64 offset, int whence) {
int rv = -1L;
AutoLock lock_scope(this);
switch (whence) {
case SEEK_CUR:
if (offset_ + offset > datasize_ || offset_ + offset < 0)
break;
offset_ += offset;
rv = 0;
break;
case SEEK_END: {
int64 offset_abs = abs(offset);
if (offset_abs > datasize_)
break;
offset_ = datasize_ - offset_abs;
rv = 0;
break;
}
case SEEK_SET:
if (offset > datasize_ || offset < 0)
break;
offset_ = offset;
rv = 0;
break;
}
return rv;
}
int64 CefBytesWriter::Tell() {
AutoLock lock_scope(this);
return offset_;
}
int CefBytesWriter::Flush() {
return 0;
}
std::string CefBytesWriter::GetDataString() {
AutoLock lock_scope(this);
std::string str(reinterpret_cast<char*>(data_), offset_);
return str;
}
size_t CefBytesWriter::Grow(size_t size) {
AutoLock lock_scope(this);
size_t rv;
size_t s = (size > grow_ ? size : grow_);
void* tmp = realloc(data_, datasize_ + s);
DCHECK(tmp != NULL);
if (tmp) {
data_ = tmp;
datasize_ += s;
rv = datasize_;
} else {
rv = 0;
}
return rv;
}

View File

@@ -0,0 +1,154 @@
// 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_BROWSER_STREAM_IMPL_H_
#define CEF_LIBCEF_BROWSER_STREAM_IMPL_H_
#pragma once
#include <stdio.h>
#include <string>
#include "include/cef_stream.h"
// Implementation of CefStreamReader for files.
class CefFileReader : public CefStreamReader {
public:
CefFileReader(FILE* file, bool close);
virtual ~CefFileReader();
virtual size_t Read(void* ptr, size_t size, size_t n) OVERRIDE;
virtual int Seek(int64 offset, int whence) OVERRIDE;
virtual int64 Tell() OVERRIDE;
virtual int Eof() OVERRIDE;
protected:
bool close_;
FILE* file_;
IMPLEMENT_REFCOUNTING(CefFileReader);
IMPLEMENT_LOCKING(CefFileReader);
};
// Implementation of CefStreamWriter for files.
class CefFileWriter : public CefStreamWriter {
public:
CefFileWriter(FILE* file, bool close);
virtual ~CefFileWriter();
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE;
virtual int Seek(int64 offset, int whence) OVERRIDE;
virtual int64 Tell() OVERRIDE;
virtual int Flush() OVERRIDE;
protected:
FILE* file_;
bool close_;
IMPLEMENT_REFCOUNTING(CefFileWriter);
IMPLEMENT_LOCKING(CefFileWriter);
};
// Implementation of CefStreamReader for byte buffers.
class CefBytesReader : public CefStreamReader {
public:
CefBytesReader(void* data, int64 datasize, bool copy);
virtual ~CefBytesReader();
virtual size_t Read(void* ptr, size_t size, size_t n) OVERRIDE;
virtual int Seek(int64 offset, int whence) OVERRIDE;
virtual int64 Tell() OVERRIDE;
virtual int Eof() OVERRIDE;
void SetData(void* data, int64 datasize, bool copy);
void* GetData() { return data_; }
size_t GetDataSize() { return offset_; }
protected:
void* data_;
int64 datasize_;
bool copy_;
int64 offset_;
IMPLEMENT_REFCOUNTING(CefBytesReader);
IMPLEMENT_LOCKING(CefBytesReader);
};
// Implementation of CefStreamWriter for byte buffers.
class CefBytesWriter : public CefStreamWriter {
public:
explicit CefBytesWriter(size_t grow);
virtual ~CefBytesWriter();
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE;
virtual int Seek(int64 offset, int whence) OVERRIDE;
virtual int64 Tell() OVERRIDE;
virtual int Flush() OVERRIDE;
void* GetData() { return data_; }
int64 GetDataSize() { return offset_; }
std::string GetDataString();
protected:
size_t Grow(size_t size);
size_t grow_;
void* data_;
int64 datasize_;
int64 offset_;
IMPLEMENT_REFCOUNTING(CefBytesWriter);
IMPLEMENT_LOCKING(CefBytesWriter);
};
// Implementation of CefStreamReader for handlers.
class CefHandlerReader : public CefStreamReader {
public:
explicit CefHandlerReader(CefRefPtr<CefReadHandler> handler)
: handler_(handler) {}
virtual size_t Read(void* ptr, size_t size, size_t n) OVERRIDE {
return handler_->Read(ptr, size, n);
}
virtual int Seek(int64 offset, int whence) OVERRIDE {
return handler_->Seek(offset, whence);
}
virtual int64 Tell() OVERRIDE {
return handler_->Tell();
}
virtual int Eof() OVERRIDE {
return handler_->Eof();
}
protected:
CefRefPtr<CefReadHandler> handler_;
IMPLEMENT_REFCOUNTING(CefHandlerReader);
};
// Implementation of CefStreamWriter for handlers.
class CefHandlerWriter : public CefStreamWriter {
public:
explicit CefHandlerWriter(CefRefPtr<CefWriteHandler> handler)
: handler_(handler) {}
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE {
return handler_->Write(ptr, size, n);
}
virtual int Seek(int64 offset, int whence) OVERRIDE {
return handler_->Seek(offset, whence);
}
virtual int64 Tell() OVERRIDE {
return handler_->Tell();
}
virtual int Flush() OVERRIDE {
return handler_->Flush();
}
protected:
CefRefPtr<CefWriteHandler> handler_;
IMPLEMENT_REFCOUNTING(CefHandlerWriter);
};
#endif // CEF_LIBCEF_BROWSER_STREAM_IMPL_H_

View File

@@ -0,0 +1,45 @@
// 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_BROWSER_THREAD_UTIL_H_
#define CEF_LIBCEF_BROWSER_THREAD_UTIL_H_
#pragma once
#include "base/location.h"
#include "base/logging.h"
#include "content/public/browser/browser_thread.h"
#define CEF_UIT content::BrowserThread::UI
#define CEF_IOT content::BrowserThread::IO
#define CEF_CURRENTLY_ON(id) content::BrowserThread::CurrentlyOn(id)
#define CEF_CURRENTLY_ON_UIT() CEF_CURRENTLY_ON(CEF_UIT)
#define CEF_CURRENTLY_ON_IOT() CEF_CURRENTLY_ON(CEF_IOT)
#define CEF_REQUIRE(id) DCHECK(CEF_CURRENTLY_ON(id))
#define CEF_REQUIRE_UIT() CEF_REQUIRE(CEF_UIT)
#define CEF_REQUIRE_IOT() CEF_REQUIRE(CEF_IOT)
#define CEF_REQUIRE_RETURN(id, var) \
if (!CEF_CURRENTLY_ON(id)) { \
NOTREACHED() << "called on invalid thread"; \
return var; \
}
#define CEF_REQUIRE_UIT_RETURN(var) CEF_REQUIRE_RETURN(CEF_UIT, var)
#define CEF_REQUIRE_IOT_RETURN(var) CEF_REQUIRE_RETURN(CEF_IOT, var)
#define CEF_REQUIRE_RETURN_VOID(id) \
if (!CEF_CURRENTLY_ON(id)) { \
NOTREACHED() << "called on invalid thread"; \
return; \
}
#define CEF_REQUIRE_UIT_RETURN_VOID() CEF_REQUIRE_RETURN_VOID(CEF_UIT)
#define CEF_REQUIRE_IOT_RETURN_VOID() CEF_REQUIRE_RETURN_VOID(CEF_IOT)
#define CEF_POST_TASK(id, task) \
content::BrowserThread::PostTask(id, FROM_HERE, task)
#define CEF_POST_DELAYED_TASK(id, task, delay_ms) \
content::BrowserThread::PostDelayedTask(id, FROM_HERE, task, delay_ms)
#endif // CEF_LIBCEF_BROWSER_THREAD_UTIL_H_

View File

@@ -0,0 +1,200 @@
// 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/browser/url_network_delegate.h"
#include <string>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/request_impl.h"
namespace {
class CefAuthCallbackImpl : public CefAuthCallback {
public:
CefAuthCallbackImpl(const net::NetworkDelegate::AuthCallback& callback,
net::AuthCredentials* credentials)
: callback_(callback),
credentials_(credentials) {
}
~CefAuthCallbackImpl() {
if (!callback_.is_null()) {
// The auth callback is still pending. Cancel it now.
if (CEF_CURRENTLY_ON_IOT()) {
CancelNow(callback_);
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefAuthCallbackImpl::CancelNow, callback_));
}
}
}
virtual void Continue(const CefString& username,
const CefString& password) OVERRIDE {
if (CEF_CURRENTLY_ON_IOT()) {
if (!callback_.is_null()) {
credentials_->Set(username, password);
callback_.Run(net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
callback_.Reset();
}
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefAuthCallbackImpl::Continue, this, username, password));
}
}
virtual void Cancel() OVERRIDE {
if (CEF_CURRENTLY_ON_IOT()) {
if (!callback_.is_null()) {
CancelNow(callback_);
callback_.Reset();
}
} else {
CEF_POST_TASK(CEF_IOT, base::Bind(&CefAuthCallbackImpl::Cancel, this));
}
}
void Disconnect() {
callback_.Reset();
}
private:
static void CancelNow(const net::NetworkDelegate::AuthCallback& callback) {
CEF_REQUIRE_IOT();
callback.Run(net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION);
}
net::NetworkDelegate::AuthCallback callback_;
net::AuthCredentials* credentials_;
IMPLEMENT_REFCOUNTING(CefAuthCallbackImpl);
};
} // namespace
CefNetworkDelegate::CefNetworkDelegate() {
}
CefNetworkDelegate::~CefNetworkDelegate() {
}
int CefNetworkDelegate::OnBeforeURLRequest(
net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
// Populate the request data.
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
requestPtr->Set(request);
// Give the client an opportunity to cancel the request.
if (handler->OnBeforeResourceLoad(browser.get(), frame,
requestPtr.get())) {
return net::ERR_ABORTED;
}
*new_url = GURL(std::string(requestPtr->GetURL()));
requestPtr->Get(request);
}
}
}
return net::OK;
}
int CefNetworkDelegate::OnBeforeSendHeaders(
net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) {
return net::OK;
}
void CefNetworkDelegate::OnSendHeaders(
net::URLRequest* request,
const net::HttpRequestHeaders& headers) {
}
int CefNetworkDelegate::OnHeadersReceived(
net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
return net::OK;
}
void CefNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) {
}
void CefNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
}
void CefNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
int bytes_read) {
}
void CefNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {
}
void CefNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
}
void CefNetworkDelegate::OnPACScriptError(int line_number,
const string16& error) {
}
net::NetworkDelegate::AuthRequiredResponse CefNetworkDelegate::OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
CefRefPtr<CefAuthCallbackImpl> callbackPtr(
new CefAuthCallbackImpl(callback, credentials));
if (handler->GetAuthCredentials(browser.get(),
frame,
auth_info.is_proxy,
auth_info.challenger.host(),
auth_info.challenger.port(),
auth_info.realm,
auth_info.scheme,
callbackPtr.get())) {
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
} else {
callbackPtr->Disconnect();
}
}
}
}
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
}
bool CefNetworkDelegate::CanGetCookies(const net::URLRequest* request,
const net::CookieList& cookie_list) {
return true;
}
bool CefNetworkDelegate::CanSetCookie(const net::URLRequest* request,
const std::string& cookie_line,
net::CookieOptions* options) {
return true;
}

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_BROWSER_URL_NETWORK_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_URL_NETWORK_DELEGATE_H_
#pragma once
#include "net/base/network_delegate.h"
// Used for intercepting resource requests, redirects and responses. The single
// instance of this class is managed by CefURLRequestContextGetter.
class CefNetworkDelegate : public net::NetworkDelegate {
public:
CefNetworkDelegate();
~CefNetworkDelegate();
private:
// net::NetworkDelegate methods.
virtual int OnBeforeURLRequest(net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) OVERRIDE;
virtual int OnBeforeSendHeaders(net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) OVERRIDE;
virtual void OnSendHeaders(net::URLRequest* request,
const net::HttpRequestHeaders& headers) OVERRIDE;
virtual int OnHeadersReceived(
net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers)
OVERRIDE;
virtual void OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) OVERRIDE;
virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
virtual void OnRawBytesRead(const net::URLRequest& request, int bytes_read)
OVERRIDE;
virtual void OnCompleted(net::URLRequest* request, bool started) OVERRIDE;
virtual void OnURLRequestDestroyed(net::URLRequest* request) OVERRIDE;
virtual void OnPACScriptError(int line_number, const string16& error)
OVERRIDE;
virtual AuthRequiredResponse OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) OVERRIDE;
virtual bool CanGetCookies(const net::URLRequest* request,
const net::CookieList& cookie_list) OVERRIDE;
virtual bool CanSetCookie(const net::URLRequest* request,
const std::string& cookie_line,
net::CookieOptions* options) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(CefNetworkDelegate);
};
#endif // CEF_LIBCEF_BROWSER_URL_NETWORK_DELEGATE_H_

View File

@@ -0,0 +1,325 @@
// 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/browser/url_request_context_getter.h"
#if defined(OS_WIN)
#include <winhttp.h>
#endif
#include <string>
#include <vector>
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_network_delegate.h"
#include "libcef/browser/url_request_interceptor.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_split.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/cert_verifier.h"
#include "net/base/default_server_bound_cert_store.h"
#include "net/base/host_resolver.h"
#include "net/base/server_bound_cert_service.h"
#include "net/base/ssl_config_service_defaults.h"
#include "net/cookies/cookie_monster.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_server_properties_impl.h"
#include "net/proxy/proxy_config_service.h"
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_job_manager.h"
using content::BrowserThread;
#if defined(OS_WIN)
#pragma comment(lib, "winhttp.lib")
#endif
namespace {
#if defined(OS_WIN)
// ProxyConfigService implementation that does nothing.
class ProxyConfigServiceNull : public net::ProxyConfigService {
public:
ProxyConfigServiceNull() {}
virtual void AddObserver(Observer* observer) OVERRIDE {}
virtual void RemoveObserver(Observer* observer) OVERRIDE {}
virtual ProxyConfigService::ConfigAvailability
GetLatestProxyConfig(net::ProxyConfig* config) OVERRIDE {
return ProxyConfigService::CONFIG_VALID;
}
virtual void OnLazyPoll() OVERRIDE {}
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceNull);
};
#endif // defined(OS_WIN)
// ProxyResolver implementation that forewards resolution to a CefProxyHandler.
class CefProxyResolver : public net::ProxyResolver {
public:
explicit CefProxyResolver(CefRefPtr<CefProxyHandler> handler)
: ProxyResolver(false),
handler_(handler) {}
virtual ~CefProxyResolver() {}
virtual int GetProxyForURL(const GURL& url,
net::ProxyInfo* results,
const net::CompletionCallback& callback,
RequestHandle* request,
const net::BoundNetLog& net_log) OVERRIDE {
CefProxyInfo proxy_info;
handler_->GetProxyForUrl(url.spec(), proxy_info);
if (proxy_info.IsDirect())
results->UseDirect();
else if (proxy_info.IsNamedProxy())
results->UseNamedProxy(proxy_info.ProxyList());
else if (proxy_info.IsPacString())
results->UsePacString(proxy_info.ProxyList());
return net::OK;
}
virtual int SetPacScript(
const scoped_refptr<net::ProxyResolverScriptData>& pac_script,
const net::CompletionCallback& callback) OVERRIDE {
return net::OK;
}
virtual void CancelRequest(RequestHandle request) OVERRIDE {}
virtual net::LoadState GetLoadState(RequestHandle request) const OVERRIDE {
return net::LOAD_STATE_IDLE;
}
virtual net::LoadState GetLoadStateThreadSafe(RequestHandle request) const
OVERRIDE {
return net::LOAD_STATE_IDLE;
}
virtual void CancelSetPacScript() OVERRIDE {}
protected:
CefRefPtr<CefProxyHandler> handler_;
DISALLOW_COPY_AND_ASSIGN(CefProxyResolver);
};
} // namespace
CefURLRequestContextGetter::CefURLRequestContextGetter(
const FilePath& base_path,
MessageLoop* io_loop,
MessageLoop* file_loop)
: base_path_(base_path),
io_loop_(io_loop),
file_loop_(file_loop) {
// Must first be created on the UI thread.
CEF_REQUIRE_UIT();
#if !defined(OS_WIN)
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
CreateProxyConfigService();
#endif
}
CefURLRequestContextGetter::~CefURLRequestContextGetter() {
}
net::URLRequestContext* CefURLRequestContextGetter::GetURLRequestContext() {
CEF_REQUIRE_IOT();
if (!url_request_context_) {
// Create the |cache_path| directory if necessary.
bool cache_path_valid = false;
const FilePath& cache_path = _Context->cache_path();
if (!cache_path.empty()) {
if (file_util::CreateDirectory(cache_path))
cache_path_valid = true;
else
NOTREACHED() << "The cache_path directory could not be created";
}
url_request_context_ = new net::URLRequestContext();
storage_.reset(new net::URLRequestContextStorage(url_request_context_));
SetCookieStoragePath(cache_path);
storage_->set_network_delegate(new CefNetworkDelegate);
storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
new net::DefaultServerBoundCertStore(NULL)));
url_request_context_->set_accept_language("en-us,en");
url_request_context_->set_accept_charset("iso-8859-1,*,utf-8");
storage_->set_host_resolver(
net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism,
net::HostResolver::kDefaultRetryAttempts,
NULL));
storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
bool proxy_service_set = false;
CefRefPtr<CefApp> app = _Context->application();
if (app.get()) {
CefRefPtr<CefProxyHandler> handler = app->GetProxyHandler();
if (handler) {
// The client will provide proxy resolution.
CreateProxyConfigService();
storage_->set_proxy_service(
new net::ProxyService(proxy_config_service_.release(),
new CefProxyResolver(handler), NULL));
proxy_service_set = true;
}
}
// TODO(jam): use v8 if possible, look at chrome code.
#if defined(OS_WIN)
if (!proxy_service_set) {
const CefSettings& settings = _Context->settings();
if (!settings.auto_detect_proxy_settings_enabled) {
// Using the system proxy resolver on Windows when "Automatically detect
// settings" (auto-detection) is checked under LAN Settings can hurt
// resource loading performance because the call to
// WinHttpGetProxyForUrl in proxy_resolver_winhttp.cc will block the
// IO thread. This is especially true for Windows 7 where auto-
// detection is checked by default. To avoid slow resource loading on
// Windows we only use the system proxy resolver if auto-detection is
// unchecked.
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
if (WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
if (ie_config.fAutoDetect == TRUE) {
storage_->set_proxy_service(
net::ProxyService::CreateWithoutProxyResolver(
new ProxyConfigServiceNull(), NULL));
proxy_service_set = true;
}
if (ie_config.lpszAutoConfigUrl)
GlobalFree(ie_config.lpszAutoConfigUrl);
if (ie_config.lpszProxy)
GlobalFree(ie_config.lpszProxy);
if (ie_config.lpszProxyBypass)
GlobalFree(ie_config.lpszProxyBypass);
}
}
}
#endif // defined(OS_WIN)
if (!proxy_service_set) {
CreateProxyConfigService();
storage_->set_proxy_service(
net::ProxyService::CreateUsingSystemProxyResolver(
proxy_config_service_.release(), 0, NULL));
}
storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
// Add support for single sign-on.
url_security_manager_.reset(net::URLSecurityManager::Create(NULL, NULL));
std::vector<std::string> supported_schemes;
supported_schemes.push_back("basic");
supported_schemes.push_back("digest");
supported_schemes.push_back("ntlm");
supported_schemes.push_back("negotiate");
storage_->set_http_auth_handler_factory(
net::HttpAuthHandlerRegistryFactory::Create(
supported_schemes,
url_security_manager_.get(),
url_request_context_->host_resolver(),
std::string(),
false,
false));
storage_->set_http_server_properties(new net::HttpServerPropertiesImpl);
net::HttpCache::DefaultBackend* main_backend =
new net::HttpCache::DefaultBackend(
cache_path_valid ? net::DISK_CACHE : net::MEMORY_CACHE,
cache_path,
0,
BrowserThread::GetMessageLoopProxyForThread(
BrowserThread::CACHE));
net::HttpCache* main_cache = new net::HttpCache(
url_request_context_->host_resolver(),
url_request_context_->cert_verifier(),
url_request_context_->server_bound_cert_service(),
NULL, // tranport_security_state
url_request_context_->proxy_service(),
"", // ssl_session_cache_shard
url_request_context_->ssl_config_service(),
url_request_context_->http_auth_handler_factory(),
NULL, // network_delegate
url_request_context_->http_server_properties(),
NULL,
main_backend);
storage_->set_http_transaction_factory(main_cache);
storage_->set_ftp_transaction_factory(
new net::FtpNetworkLayer(url_request_context_->host_resolver()));
storage_->set_job_factory(new net::URLRequestJobFactory);
request_interceptor_.reset(new CefRequestInterceptor);
}
return url_request_context_;
}
scoped_refptr<base::MessageLoopProxy>
CefURLRequestContextGetter::GetIOMessageLoopProxy() const {
return BrowserThread::GetMessageLoopProxyForThread(CEF_IOT);
}
net::HostResolver* CefURLRequestContextGetter::host_resolver() {
return url_request_context_->host_resolver();
}
void CefURLRequestContextGetter::SetCookieStoragePath(const FilePath& path) {
CEF_REQUIRE_IOT();
if (url_request_context_->cookie_store() &&
((cookie_store_path_.empty() && path.empty()) ||
cookie_store_path_ == path)) {
// The path has not changed so don't do anything.
return;
}
scoped_refptr<SQLitePersistentCookieStore> persistent_store;
if (!path.empty()) {
if (file_util::CreateDirectory(path)) {
const FilePath& cookie_path = path.AppendASCII("Cookies");
persistent_store = new SQLitePersistentCookieStore(cookie_path, false);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
storage_->set_cookie_store(
new net::CookieMonster(persistent_store.get(), NULL));
cookie_store_path_ = path;
}
void CefURLRequestContextGetter::CreateProxyConfigService() {
if (proxy_config_service_.get())
return;
proxy_config_service_.reset(
net::ProxyService::CreateSystemProxyConfigService(io_loop_, file_loop_));
}

View File

@@ -0,0 +1,62 @@
// 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_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
#pragma once
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/url_request/url_request_context_getter.h"
class CefRequestInterceptor;
class MessageLoop;
namespace net {
class HostResolver;
class ProxyConfigService;
class URLRequestContextStorage;
class URLRequestJobFactory;
class URLSecurityManager;
}
class CefURLRequestContextGetter : public net::URLRequestContextGetter {
public:
CefURLRequestContextGetter(
const FilePath& base_path_,
MessageLoop* io_loop,
MessageLoop* file_loop);
virtual ~CefURLRequestContextGetter();
// net::URLRequestContextGetter implementation.
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
virtual scoped_refptr<base::MessageLoopProxy>
GetIOMessageLoopProxy() const OVERRIDE;
net::HostResolver* host_resolver();
void SetCookieStoragePath(const FilePath& path);
private:
void CreateProxyConfigService();
FilePath base_path_;
MessageLoop* io_loop_;
MessageLoop* file_loop_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_refptr<net::URLRequestContext> url_request_context_;
scoped_ptr<net::URLSecurityManager> url_security_manager_;
scoped_ptr<net::URLRequestContextStorage> storage_;
scoped_ptr<CefRequestInterceptor> request_interceptor_;
FilePath cookie_store_path_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetter);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_

View File

@@ -0,0 +1,177 @@
// 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/browser/url_request_context_getter_proxy.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/cookie_manager_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context.h"
namespace {
class CefCookieStoreProxy : public net::CookieStore {
public:
explicit CefCookieStoreProxy(CefBrowserHostImpl* browser,
net::URLRequestContext* parent)
: parent_(parent),
browser_(browser) {
}
// net::CookieStore methods.
virtual void SetCookieWithOptionsAsync(
const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options,
const SetCookiesCallback& callback) OVERRIDE {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->SetCookieWithOptionsAsync(url, cookie_line, options,
callback);
}
virtual void GetCookiesWithOptionsAsync(
const GURL& url, const net::CookieOptions& options,
const GetCookiesCallback& callback) OVERRIDE {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->GetCookiesWithOptionsAsync(url, options, callback);
}
void GetCookiesWithInfoAsync(
const GURL& url,
const net::CookieOptions& options,
const GetCookieInfoCallback& callback) OVERRIDE {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->GetCookiesWithInfoAsync(url, options, callback);
}
virtual void DeleteCookieAsync(const GURL& url,
const std::string& cookie_name,
const base::Closure& callback) OVERRIDE {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteCookieAsync(url, cookie_name, callback);
}
virtual void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
const base::Time& delete_end,
const DeleteCallback& callback)
OVERRIDE {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
cookie_store->DeleteAllCreatedBetweenAsync(delete_begin, delete_end,
callback);
}
virtual net::CookieMonster* GetCookieMonster() OVERRIDE {
scoped_refptr<net::CookieStore> cookie_store = GetCookieStore();
return cookie_store->GetCookieMonster();
}
private:
net::CookieStore* GetCookieStore() {
CEF_REQUIRE_IOT();
scoped_refptr<net::CookieStore> cookie_store;
CefRefPtr<CefClient> client = browser_->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
// Get the manager from the handler.
CefRefPtr<CefCookieManager> manager =
handler->GetCookieManager(browser_,
browser_->GetLoadingURL().spec());
if (manager.get()) {
cookie_store =
reinterpret_cast<CefCookieManagerImpl*>(
manager.get())->cookie_monster();
DCHECK(cookie_store);
}
}
}
if (!cookie_store) {
// Use the global cookie store.
cookie_store = parent_->cookie_store();
}
DCHECK(cookie_store);
return cookie_store;
}
// This pointer is guaranteed by the CefRequestContextProxy object.
net::URLRequestContext* parent_;
CefBrowserHostImpl* browser_;
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy);
};
class CefRequestContextProxy : public net::URLRequestContext {
public:
CefRequestContextProxy(CefBrowserHostImpl* browser,
net::URLRequestContext* parent)
: parent_(parent) {
// Cookie store that proxies to the browser implementation.
cookie_store_proxy_ = new CefCookieStoreProxy(browser, parent_);
set_cookie_store(cookie_store_proxy_);
// All other values refer to the parent request context.
set_net_log(parent_->net_log());
set_host_resolver(parent_->host_resolver());
set_cert_verifier(parent_->cert_verifier());
set_server_bound_cert_service(parent_->server_bound_cert_service());
set_fraudulent_certificate_reporter(
parent_->fraudulent_certificate_reporter());
set_proxy_service(parent_->proxy_service());
set_ssl_config_service(parent_->ssl_config_service());
set_http_auth_handler_factory(parent_->http_auth_handler_factory());
set_http_transaction_factory(parent_->http_transaction_factory());
set_ftp_transaction_factory(parent_->ftp_transaction_factory());
set_network_delegate(parent_->network_delegate());
set_http_server_properties(parent_->http_server_properties());
set_transport_security_state(parent_->transport_security_state());
set_accept_charset(parent_->accept_charset());
set_accept_language(parent_->accept_language());
set_referrer_charset(parent_->referrer_charset());
set_job_factory(parent_->job_factory());
}
virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE {
return parent_->GetUserAgent(url);
}
private:
scoped_refptr<net::URLRequestContext> parent_;
scoped_refptr<net::CookieStore> cookie_store_proxy_;
DISALLOW_COPY_AND_ASSIGN(CefRequestContextProxy);
};
} // namespace
CefURLRequestContextGetterProxy::CefURLRequestContextGetterProxy(
CefBrowserHostImpl* browser,
net::URLRequestContextGetter* parent)
: browser_(browser),
parent_(parent) {
DCHECK(browser);
DCHECK(parent);
}
net::URLRequestContext*
CefURLRequestContextGetterProxy::GetURLRequestContext() {
CEF_REQUIRE_IOT();
if (!context_proxy_) {
context_proxy_ =
new CefRequestContextProxy(browser_, parent_->GetURLRequestContext());
}
return context_proxy_;
}
scoped_refptr<base::MessageLoopProxy>
CefURLRequestContextGetterProxy::GetIOMessageLoopProxy() const {
return parent_->GetIOMessageLoopProxy();
}

View File

@@ -0,0 +1,31 @@
// 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_BROWSER_URL_REQUEST_CONTEXT_GETTER_PROXY_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_PROXY_H_
#pragma once
#include "net/url_request/url_request_context_getter.h"
class CefBrowserHostImpl;
class CefURLRequestContextGetterProxy : public net::URLRequestContextGetter {
public:
CefURLRequestContextGetterProxy(CefBrowserHostImpl* browser,
net::URLRequestContextGetter* parent);
// net::URLRequestContextGetter implementation.
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
virtual scoped_refptr<base::MessageLoopProxy>
GetIOMessageLoopProxy() const OVERRIDE;
private:
CefBrowserHostImpl* browser_;
scoped_refptr<net::URLRequestContextGetter> parent_;
scoped_refptr<net::URLRequestContext> context_proxy_;
DISALLOW_COPY_AND_ASSIGN(CefURLRequestContextGetterProxy);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_CONTEXT_GETTER_PROXY_H_

View File

@@ -0,0 +1,85 @@
// 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/browser/url_request_interceptor.h"
#include <string>
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/resource_request_job.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/request_impl.h"
#include "net/url_request/url_request_job_manager.h"
#include "net/url_request/url_request_redirect_job.h"
CefRequestInterceptor::CefRequestInterceptor() {
CEF_REQUIRE_IOT();
net::URLRequestJobManager::GetInstance()->RegisterRequestInterceptor(this);
}
CefRequestInterceptor::~CefRequestInterceptor() {
CEF_REQUIRE_IOT();
net::URLRequestJobManager::GetInstance()->
UnregisterRequestInterceptor(this);
}
net::URLRequestJob* CefRequestInterceptor::MaybeIntercept(
net::URLRequest* request) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
// Populate the request data.
CefRefPtr<CefRequest> req(CefRequest::CreateRequest());
static_cast<CefRequestImpl*>(req.get())->Set(request);
// Give the client an opportunity to replace the request.
CefRefPtr<CefResourceHandler> resourceHandler =
handler->GetResourceHandler(browser.get(), frame, req);
if (resourceHandler.get())
return new CefResourceRequestJob(request, resourceHandler);
}
}
}
return NULL;
}
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRedirect(
net::URLRequest* request, const GURL& location) {
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForRequest(request);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
// Give the client an opportunity to redirect the request.
CefString newUrlStr = location.spec();
handler->OnResourceRedirect(browser.get(), frame, request->url().spec(),
newUrlStr);
if (newUrlStr != location.spec()) {
GURL new_url = GURL(std::string(newUrlStr));
if (!new_url.is_empty() && new_url.is_valid())
return new net::URLRequestRedirectJob(request, new_url);
}
}
}
}
return NULL;
}
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse(
net::URLRequest* request) {
return NULL;
}

View File

@@ -0,0 +1,29 @@
// 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_BROWSER_URL_REQUEST_INTERCEPTOR_H_
#define CEF_LIBCEF_BROWSER_URL_REQUEST_INTERCEPTOR_H_
#pragma once
#include "net/url_request/url_request.h"
// Used for intercepting resource requests, redirects and responses. The single
// instance of this class is managed by CefURLRequestContextGetter.
class CefRequestInterceptor : public net::URLRequest::Interceptor {
public:
CefRequestInterceptor();
~CefRequestInterceptor();
// net::URLRequest::Interceptor methods.
virtual net::URLRequestJob* MaybeIntercept(net::URLRequest* request)
OVERRIDE;
virtual net::URLRequestJob* MaybeInterceptRedirect(net::URLRequest* request,
const GURL& location) OVERRIDE;
virtual net::URLRequestJob* MaybeInterceptResponse(net::URLRequest* request)
OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(CefRequestInterceptor);
};
#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_INTERCEPTOR_H_

View File

@@ -0,0 +1,446 @@
// 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/browser/xml_reader_impl.h"
#include "include/cef_stream.h"
#include "base/logging.h"
// Static functions
// static
CefRefPtr<CefXmlReader> CefXmlReader::Create(CefRefPtr<CefStreamReader> stream,
EncodingType encodingType,
const CefString& URI) {
CefRefPtr<CefXmlReaderImpl> impl(new CefXmlReaderImpl());
if (!impl->Initialize(stream, encodingType, URI))
return NULL;
return impl.get();
}
// CefXmlReaderImpl
namespace {
/**
* xmlInputReadCallback:
* @context: an Input context
* @buffer: the buffer to store data read
* @len: the length of the buffer in bytes
*
* Callback used in the I/O Input API to read the resource
*
* Returns the number of bytes read or -1 in case of error
*/
int XMLCALL xml_read_callback(void * context, char * buffer, int len) {
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(context));
return reader->Read(buffer, 1, len);
}
/**
* xmlTextReaderErrorFunc:
* @arg: the user argument
* @msg: the message
* @severity: the severity of the error
* @locator: a locator indicating where the error occured
*
* Signature of an error callback from a reader parser
*/
void XMLCALL xml_error_callback(void *arg, const char *msg,
xmlParserSeverities severity,
xmlTextReaderLocatorPtr locator) {
if (!msg)
return;
std::string error_str(msg);
if (!error_str.empty() && error_str[error_str.length()-1] == '\n')
error_str.resize(error_str.length()-1);
std::stringstream ss;
ss << error_str << ", line " << xmlTextReaderLocatorLineNumber(locator);
LOG(INFO) << ss.str();
CefRefPtr<CefXmlReaderImpl> impl(static_cast<CefXmlReaderImpl*>(arg));
impl->AppendError(ss.str());
}
/**
* xmlStructuredErrorFunc:
* @userData: user provided data for the error callback
* @error: the error being raised.
*
* Signature of the function to use when there is an error and
* the module handles the new error reporting mechanism.
*/
void XMLCALL xml_structured_error_callback(void *userData, xmlErrorPtr error) {
if (!error->message)
return;
std::string error_str(error->message);
if (!error_str.empty() && error_str[error_str.length()-1] == '\n')
error_str.resize(error_str.length()-1);
std::stringstream ss;
ss << error_str << ", line " << error->line;
LOG(INFO) << ss.str();
CefRefPtr<CefXmlReaderImpl> impl(static_cast<CefXmlReaderImpl*>(userData));
impl->AppendError(ss.str());
}
CefString xmlCharToString(const xmlChar* xmlStr, bool free) {
if (!xmlStr)
return CefString();
const char* str = reinterpret_cast<const char*>(xmlStr);
CefString wstr = std::string(str);
if (free)
xmlFree(const_cast<xmlChar*>(xmlStr));
return wstr;
}
} // namespace
CefXmlReaderImpl::CefXmlReaderImpl()
: supported_thread_id_(base::PlatformThread::CurrentId()), reader_(NULL) {
}
CefXmlReaderImpl::~CefXmlReaderImpl() {
if (reader_ != NULL) {
if (!VerifyContext()) {
// Close() is supposed to be called directly. We'll try to free the reader
// now on the wrong thread but there's no guarantee this call won't crash.
xmlFreeTextReader(reader_);
} else {
Close();
}
}
}
bool CefXmlReaderImpl::Initialize(CefRefPtr<CefStreamReader> stream,
EncodingType encodingType,
const CefString& URI) {
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
switch (encodingType) {
case XML_ENCODING_UTF8:
enc = XML_CHAR_ENCODING_UTF8;
break;
case XML_ENCODING_UTF16LE:
enc = XML_CHAR_ENCODING_UTF16LE;
break;
case XML_ENCODING_UTF16BE:
enc = XML_CHAR_ENCODING_UTF16BE;
break;
case XML_ENCODING_ASCII:
enc = XML_CHAR_ENCODING_ASCII;
break;
default:
break;
}
// Create the input buffer.
xmlParserInputBufferPtr input_buffer = xmlAllocParserInputBuffer(enc);
if (!input_buffer)
return false;
input_buffer->context = stream.get();
input_buffer->readcallback = xml_read_callback;
// Create the text reader.
std::string uriStr = URI;
reader_ = xmlNewTextReader(input_buffer, uriStr.c_str());
if (!reader_) {
// Free the input buffer.
xmlFreeParserInputBuffer(input_buffer);
return false;
}
// Keep a reference to the stream.
stream_ = stream;
// Register the error callbacks.
xmlTextReaderSetErrorHandler(reader_, xml_error_callback, this);
xmlTextReaderSetStructuredErrorHandler(reader_,
xml_structured_error_callback, this);
return true;
}
bool CefXmlReaderImpl::MoveToNextNode() {
if (!VerifyContext())
return false;
return xmlTextReaderRead(reader_) == 1 ? true : false;
}
bool CefXmlReaderImpl::Close() {
if (!VerifyContext())
return false;
// The input buffer will be freed automatically.
xmlFreeTextReader(reader_);
reader_ = NULL;
return true;
}
bool CefXmlReaderImpl::HasError() {
if (!VerifyContext())
return false;
return !error_buf_.str().empty();
}
CefString CefXmlReaderImpl::GetError() {
if (!VerifyContext())
return CefString();
return error_buf_.str();
}
CefXmlReader::NodeType CefXmlReaderImpl::GetType() {
if (!VerifyContext())
return XML_NODE_UNSUPPORTED;
switch (xmlTextReaderNodeType(reader_)) {
case XML_READER_TYPE_ELEMENT:
return XML_NODE_ELEMENT_START;
case XML_READER_TYPE_END_ELEMENT:
return XML_NODE_ELEMENT_END;
case XML_READER_TYPE_ATTRIBUTE:
return XML_NODE_ATTRIBUTE;
case XML_READER_TYPE_TEXT:
return XML_NODE_TEXT;
case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
case XML_READER_TYPE_WHITESPACE:
return XML_NODE_WHITESPACE;
case XML_READER_TYPE_CDATA:
return XML_NODE_CDATA;
case XML_READER_TYPE_ENTITY_REFERENCE:
return XML_NODE_ENTITY_REFERENCE;
case XML_READER_TYPE_PROCESSING_INSTRUCTION:
return XML_NODE_PROCESSING_INSTRUCTION;
case XML_READER_TYPE_COMMENT:
return XML_NODE_COMMENT;
case XML_READER_TYPE_DOCUMENT_TYPE:
return XML_NODE_DOCUMENT_TYPE;
default:
break;
}
return XML_NODE_UNSUPPORTED;
}
int CefXmlReaderImpl::GetDepth() {
if (!VerifyContext())
return -1;
return xmlTextReaderDepth(reader_);
}
CefString CefXmlReaderImpl::GetLocalName() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderConstLocalName(reader_), false);
}
CefString CefXmlReaderImpl::GetPrefix() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderConstPrefix(reader_), false);
}
CefString CefXmlReaderImpl::GetQualifiedName() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderConstName(reader_), false);
}
CefString CefXmlReaderImpl::GetNamespaceURI() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderConstNamespaceUri(reader_), false);
}
CefString CefXmlReaderImpl::GetBaseURI() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderConstBaseUri(reader_), false);
}
CefString CefXmlReaderImpl::GetXmlLang() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderConstXmlLang(reader_), false);
}
bool CefXmlReaderImpl::IsEmptyElement() {
if (!VerifyContext())
return false;
return xmlTextReaderIsEmptyElement(reader_) == 1 ? true : false;
}
bool CefXmlReaderImpl::HasValue() {
if (!VerifyContext())
return false;
if (xmlTextReaderNodeType(reader_) == XML_READER_TYPE_ENTITY_REFERENCE) {
// Provide special handling to return entity reference values.
return true;
} else {
return xmlTextReaderHasValue(reader_) == 1 ? true : false;
}
}
CefString CefXmlReaderImpl::GetValue() {
if (!VerifyContext())
return CefString();
if (xmlTextReaderNodeType(reader_) == XML_READER_TYPE_ENTITY_REFERENCE) {
// Provide special handling to return entity reference values.
xmlNodePtr node = xmlTextReaderCurrentNode(reader_);
if (node->content != NULL)
return xmlCharToString(node->content, false);
return CefString();
} else {
return xmlCharToString(xmlTextReaderConstValue(reader_), false);
}
}
bool CefXmlReaderImpl::HasAttributes() {
if (!VerifyContext())
return false;
return xmlTextReaderHasAttributes(reader_) == 1 ? true : false;
}
size_t CefXmlReaderImpl::GetAttributeCount() {
if (!VerifyContext())
return 0;
return xmlTextReaderAttributeCount(reader_);
}
CefString CefXmlReaderImpl::GetAttribute(int index) {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderGetAttributeNo(reader_, index), true);
}
CefString CefXmlReaderImpl::GetAttribute(const CefString& qualifiedName) {
if (!VerifyContext())
return CefString();
std::string qualifiedNameStr = qualifiedName;
return xmlCharToString(xmlTextReaderGetAttribute(reader_,
BAD_CAST qualifiedNameStr.c_str()), true);
}
CefString CefXmlReaderImpl::GetAttribute(const CefString& localName,
const CefString& namespaceURI) {
if (!VerifyContext())
return CefString();
std::string localNameStr = localName;
std::string namespaceURIStr = namespaceURI;
return xmlCharToString(xmlTextReaderGetAttributeNs(reader_,
BAD_CAST localNameStr.c_str(), BAD_CAST namespaceURIStr.c_str()), true);
}
CefString CefXmlReaderImpl::GetInnerXml() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderReadInnerXml(reader_), true);
}
CefString CefXmlReaderImpl::GetOuterXml() {
if (!VerifyContext())
return CefString();
return xmlCharToString(xmlTextReaderReadOuterXml(reader_), true);
}
int CefXmlReaderImpl::GetLineNumber() {
if (!VerifyContext())
return -1;
return xmlTextReaderGetParserLineNumber(reader_);
}
bool CefXmlReaderImpl::MoveToAttribute(int index) {
if (!VerifyContext())
return false;
return xmlTextReaderMoveToAttributeNo(reader_, index) == 1 ? true : false;
}
bool CefXmlReaderImpl::MoveToAttribute(const CefString& qualifiedName) {
if (!VerifyContext())
return false;
std::string qualifiedNameStr = qualifiedName;
return xmlTextReaderMoveToAttribute(reader_,
BAD_CAST qualifiedNameStr.c_str()) == 1 ? true : false;
}
bool CefXmlReaderImpl::MoveToAttribute(const CefString& localName,
const CefString& namespaceURI) {
if (!VerifyContext())
return false;
std::string localNameStr = localName;
std::string namespaceURIStr = namespaceURI;
return xmlTextReaderMoveToAttributeNs(reader_,
BAD_CAST localNameStr.c_str(), BAD_CAST namespaceURIStr.c_str()) == 1 ?
true : false;
}
bool CefXmlReaderImpl::MoveToFirstAttribute() {
if (!VerifyContext())
return false;
return xmlTextReaderMoveToFirstAttribute(reader_) == 1 ? true : false;
}
bool CefXmlReaderImpl::MoveToNextAttribute() {
if (!VerifyContext())
return false;
return xmlTextReaderMoveToNextAttribute(reader_) == 1 ? true : false;
}
bool CefXmlReaderImpl::MoveToCarryingElement() {
if (!VerifyContext())
return false;
return xmlTextReaderMoveToElement(reader_) == 1 ? true : false;
}
void CefXmlReaderImpl::AppendError(const CefString& error_str) {
if (!error_buf_.str().empty())
error_buf_ << L"\n";
error_buf_ << error_str;
}
bool CefXmlReaderImpl::VerifyContext() {
if (base::PlatformThread::CurrentId() != supported_thread_id_) {
// This object should only be accessed from the thread that created it.
NOTREACHED();
return false;
}
return (reader_ != NULL);
}

View File

@@ -0,0 +1,73 @@
// 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_BROWSER_XML_READER_IMPL_H_
#define CEF_LIBCEF_BROWSER_XML_READER_IMPL_H_
#pragma once
#include <libxml/xmlreader.h>
#include <sstream>
#include "include/cef_xml_reader.h"
#include "base/threading/platform_thread.h"
// Implementation of CefXmlReader
class CefXmlReaderImpl : public CefXmlReader {
public:
CefXmlReaderImpl();
~CefXmlReaderImpl();
// Initialize the reader context.
bool Initialize(CefRefPtr<CefStreamReader> stream,
EncodingType encodingType, const CefString& URI);
virtual bool MoveToNextNode() OVERRIDE;
virtual bool Close() OVERRIDE;
virtual bool HasError() OVERRIDE;
virtual CefString GetError() OVERRIDE;
virtual NodeType GetType() OVERRIDE;
virtual int GetDepth() OVERRIDE;
virtual CefString GetLocalName() OVERRIDE;
virtual CefString GetPrefix() OVERRIDE;
virtual CefString GetQualifiedName() OVERRIDE;
virtual CefString GetNamespaceURI() OVERRIDE;
virtual CefString GetBaseURI() OVERRIDE;
virtual CefString GetXmlLang() OVERRIDE;
virtual bool IsEmptyElement() OVERRIDE;
virtual bool HasValue() OVERRIDE;
virtual CefString GetValue() OVERRIDE;
virtual bool HasAttributes() OVERRIDE;
virtual size_t GetAttributeCount() OVERRIDE;
virtual CefString GetAttribute(int index) OVERRIDE;
virtual CefString GetAttribute(const CefString& qualifiedName) OVERRIDE;
virtual CefString GetAttribute(const CefString& localName,
const CefString& namespaceURI) OVERRIDE;
virtual CefString GetInnerXml() OVERRIDE;
virtual CefString GetOuterXml() OVERRIDE;
virtual int GetLineNumber() OVERRIDE;
virtual bool MoveToAttribute(int index) OVERRIDE;
virtual bool MoveToAttribute(const CefString& qualifiedName) OVERRIDE;
virtual bool MoveToAttribute(const CefString& localName,
const CefString& namespaceURI) OVERRIDE;
virtual bool MoveToFirstAttribute() OVERRIDE;
virtual bool MoveToNextAttribute() OVERRIDE;
virtual bool MoveToCarryingElement() OVERRIDE;
// Add another line to the error string.
void AppendError(const CefString& error_str);
// Verify that the reader exists and is being accessed from the correct
// thread.
bool VerifyContext();
protected:
base::PlatformThreadId supported_thread_id_;
CefRefPtr<CefStreamReader> stream_;
xmlTextReaderPtr reader_;
std::stringstream error_buf_;
IMPLEMENT_REFCOUNTING(CefXMLReaderImpl);
};
#endif // CEF_LIBCEF_BROWSER_XML_READER_IMPL_H_

View File

@@ -0,0 +1,280 @@
// 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/browser/zip_reader_impl.h"
#include <time.h>
#include "include/cef_stream.h"
#include "base/logging.h"
// Static functions
// static
CefRefPtr<CefZipReader> CefZipReader::Create(
CefRefPtr<CefStreamReader> stream) {
CefRefPtr<CefZipReaderImpl> impl(new CefZipReaderImpl());
if (!impl->Initialize(stream))
return NULL;
return impl.get();
}
// CefZipReaderImpl
namespace {
voidpf ZCALLBACK zlib_open_callback OF((voidpf opaque, const void* filename,
int mode)) {
// The stream is already implicitly open so just return the pointer.
return opaque;
}
uLong ZCALLBACK zlib_read_callback OF((voidpf opaque, voidpf stream, void* buf,
uLong size)) {
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(opaque));
return reader->Read(buf, 1, size);
}
ZPOS64_T ZCALLBACK zlib_tell_callback OF((voidpf opaque, voidpf stream)) {
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(opaque));
return reader->Tell();
}
long ZCALLBACK zlib_seek_callback OF((voidpf opaque, // NOLINT(runtime/int)
voidpf stream, ZPOS64_T offset,
int origin)) {
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(opaque));
int whence;
switch (origin) {
case ZLIB_FILEFUNC_SEEK_CUR:
whence = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END:
whence = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET:
whence = SEEK_SET;
break;
default:
NOTREACHED();
return -1;
}
return reader->Seek(offset, whence);
}
int ZCALLBACK zlib_close_callback OF((voidpf opaque, voidpf stream)) {
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(opaque));
// Release the reference added by CefZipReaderImpl::Initialize().
reader->Release();
return 0;
}
int ZCALLBACK zlib_error_callback OF((voidpf opaque, voidpf stream)) {
return 0;
}
} // namespace
CefZipReaderImpl::CefZipReaderImpl()
: supported_thread_id_(base::PlatformThread::CurrentId()), reader_(NULL),
has_fileopen_(false),
has_fileinfo_(false),
filesize_(0),
filemodified_(0) {
}
CefZipReaderImpl::~CefZipReaderImpl() {
if (reader_ != NULL) {
if (!VerifyContext()) {
// Close() is supposed to be called directly. We'll try to free the reader
// now on the wrong thread but there's no guarantee this call won't crash.
if (has_fileopen_)
unzCloseCurrentFile(reader_);
unzClose(reader_);
} else {
Close();
}
}
}
bool CefZipReaderImpl::Initialize(CefRefPtr<CefStreamReader> stream) {
zlib_filefunc64_def filefunc_def;
filefunc_def.zopen64_file = zlib_open_callback;
filefunc_def.zread_file = zlib_read_callback;
filefunc_def.zwrite_file = NULL;
filefunc_def.ztell64_file = zlib_tell_callback;
filefunc_def.zseek64_file = zlib_seek_callback;
filefunc_def.zclose_file = zlib_close_callback;
filefunc_def.zerror_file = zlib_error_callback;
filefunc_def.opaque = stream.get();
// Add a reference that will be released by zlib_close_callback().
stream->AddRef();
reader_ = unzOpen2_64("", &filefunc_def);
return (reader_ != NULL);
}
bool CefZipReaderImpl::MoveToFirstFile() {
if (!VerifyContext())
return false;
if (has_fileopen_)
CloseFile();
has_fileinfo_ = false;
return (unzGoToFirstFile(reader_) == UNZ_OK);
}
bool CefZipReaderImpl::MoveToNextFile() {
if (!VerifyContext())
return false;
if (has_fileopen_)
CloseFile();
has_fileinfo_ = false;
return (unzGoToNextFile(reader_) == UNZ_OK);
}
bool CefZipReaderImpl::MoveToFile(const CefString& fileName,
bool caseSensitive) {
if (!VerifyContext())
return false;
if (has_fileopen_)
CloseFile();
has_fileinfo_ = false;
std::string fileNameStr = fileName;
return (unzLocateFile(reader_, fileNameStr.c_str(),
(caseSensitive ? 1 : 2)) == UNZ_OK);
}
bool CefZipReaderImpl::Close() {
if (!VerifyContext())
return false;
if (has_fileopen_)
CloseFile();
int result = unzClose(reader_);
reader_ = NULL;
return (result == UNZ_OK);
}
CefString CefZipReaderImpl::GetFileName() {
if (!VerifyContext() || !GetFileInfo())
return CefString();
return filename_;
}
int64 CefZipReaderImpl::GetFileSize() {
if (!VerifyContext() || !GetFileInfo())
return -1;
return filesize_;
}
time_t CefZipReaderImpl::GetFileLastModified() {
if (!VerifyContext() || !GetFileInfo())
return 0;
return filemodified_;
}
bool CefZipReaderImpl::OpenFile(const CefString& password) {
if (!VerifyContext())
return false;
if (has_fileopen_)
CloseFile();
bool ret;
if (password.empty()) {
ret = (unzOpenCurrentFile(reader_) == UNZ_OK);
} else {
std::string passwordStr = password;
ret = (unzOpenCurrentFilePassword(reader_, passwordStr.c_str()) == UNZ_OK);
}
if (ret)
has_fileopen_ = true;
return ret;
}
bool CefZipReaderImpl::CloseFile() {
if (!VerifyContext() || !has_fileopen_)
return false;
has_fileopen_ = false;
has_fileinfo_ = false;
return (unzCloseCurrentFile(reader_) == UNZ_OK);
}
int CefZipReaderImpl::ReadFile(void* buffer, size_t bufferSize) {
if (!VerifyContext() || !has_fileopen_)
return -1;
return unzReadCurrentFile(reader_, buffer, bufferSize);
}
int64 CefZipReaderImpl::Tell() {
if (!VerifyContext() || !has_fileopen_)
return -1;
return unztell64(reader_);
}
bool CefZipReaderImpl::Eof() {
if (!VerifyContext() || !has_fileopen_)
return true;
return (unzeof(reader_) == 1 ? true : false);
}
bool CefZipReaderImpl::GetFileInfo() {
if (has_fileinfo_)
return true;
char file_name[512] = {0};
unz_file_info file_info;
memset(&file_info, 0, sizeof(file_info));
if (unzGetCurrentFileInfo(reader_, &file_info, file_name, sizeof(file_name),
NULL, 0, NULL, 0) != UNZ_OK) {
return false;
}
has_fileinfo_ = true;
filename_ = std::string(file_name);
filesize_ = file_info.uncompressed_size;
struct tm time;
memset(&time, 0, sizeof(time));
time.tm_sec = file_info.tmu_date.tm_sec;
time.tm_min = file_info.tmu_date.tm_min;
time.tm_hour = file_info.tmu_date.tm_hour;
time.tm_mday = file_info.tmu_date.tm_mday;
time.tm_mon = file_info.tmu_date.tm_mon;
time.tm_year = file_info.tmu_date.tm_year;
filemodified_ = mktime(&time);
return true;
}
bool CefZipReaderImpl::VerifyContext() {
if (base::PlatformThread::CurrentId() != supported_thread_id_) {
// This object should only be accessed from the thread that created it.
NOTREACHED();
return false;
}
return (reader_ != NULL);
}

View File

@@ -0,0 +1,55 @@
// 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_BROWSER_ZIP_READER_IMPL_H_
#define CEF_LIBCEF_BROWSER_ZIP_READER_IMPL_H_
#pragma once
#include <sstream>
#include "include/cef_zip_reader.h"
#include "base/threading/platform_thread.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
// Implementation of CefZipReader
class CefZipReaderImpl : public CefZipReader {
public:
CefZipReaderImpl();
~CefZipReaderImpl();
// Initialize the reader context.
bool Initialize(CefRefPtr<CefStreamReader> stream);
virtual bool MoveToFirstFile();
virtual bool MoveToNextFile();
virtual bool MoveToFile(const CefString& fileName, bool caseSensitive);
virtual bool Close();
virtual CefString GetFileName();
virtual int64 GetFileSize();
virtual time_t GetFileLastModified();
virtual bool OpenFile(const CefString& password);
virtual bool CloseFile();
virtual int ReadFile(void* buffer, size_t bufferSize);
virtual int64 Tell();
virtual bool Eof();
bool GetFileInfo();
// Verify that the reader exists and is being accessed from the correct
// thread.
bool VerifyContext();
protected:
base::PlatformThreadId supported_thread_id_;
unzFile reader_;
bool has_fileopen_;
bool has_fileinfo_;
CefString filename_;
int64 filesize_;
time_t filemodified_;
IMPLEMENT_REFCOUNTING(CefZipReaderImpl);
};
#endif // CEF_LIBCEF_BROWSER_ZIP_READER_IMPL_H_

View File

@@ -0,0 +1,33 @@
// 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.
// Get basic type definitions.
#define IPC_MESSAGE_IMPL
#include "libcef/common/cef_message_generator.h"
// Generate constructors.
#include "ipc/struct_constructor_macros.h"
#include "libcef/common/cef_message_generator.h"
// Generate destructors.
#include "ipc/struct_destructor_macros.h"
#include "libcef/common/cef_message_generator.h"
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
#include "libcef/common/cef_message_generator.h"
} // namespace IPC
// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
#include "libcef/common/cef_message_generator.h"
} // namespace IPC
// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
#include "libcef/common/cef_message_generator.h"
} // namespace IPC

View File

@@ -0,0 +1,7 @@
// 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.
// Multiply-included file, hence no include guard.
#include "libcef/common/cef_messages.h"

View File

@@ -0,0 +1,178 @@
// 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.
// IPC messages for CEF.
// Multiply-included message file, hence no include guard.
#include "base/shared_memory.h"
#include "base/values.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/common/referrer.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/upload_data.h"
// TODO(cef): Re-using the message start for extensions may be problematic in
// the future. It would be better if ipc_message_utils.h contained a value
// reserved for consumers of the content API.
// See: http://crbug.com/110911
#define IPC_MESSAGE_START ExtensionMsgStart
// Common types.
// Parameters structure for a request.
IPC_STRUCT_BEGIN(Cef_Request_Params)
// Unique request id to match requests and responses.
IPC_STRUCT_MEMBER(int, request_id)
// Unique id of the target frame. -1 if unknown / invalid.
IPC_STRUCT_MEMBER(int64, frame_id)
// True if the request is user-initiated instead of internal.
IPC_STRUCT_MEMBER(bool, user_initiated)
// True if a response is expected.
IPC_STRUCT_MEMBER(bool, expect_response)
// Message name.
IPC_STRUCT_MEMBER(std::string, name)
// List of message arguments.
IPC_STRUCT_MEMBER(ListValue, arguments)
IPC_STRUCT_END()
// Parameters structure for a response.
IPC_STRUCT_BEGIN(Cef_Response_Params)
// Unique request id to match requests and responses.
IPC_STRUCT_MEMBER(int, request_id)
// True if a response ack is expected.
IPC_STRUCT_MEMBER(bool, expect_response_ack)
// True on success.
IPC_STRUCT_MEMBER(bool, success)
// Response or error string depending on the value of |success|.
IPC_STRUCT_MEMBER(std::string, response)
IPC_STRUCT_END()
// Messages sent from the browser to the renderer.
// Tell the renderer which browser window it's being attached to.
IPC_MESSAGE_ROUTED2(CefMsg_UpdateBrowserWindowId,
int /* browser_id */,
bool /* is_popup */)
// Parameters for a resource request.
IPC_STRUCT_BEGIN(CefMsg_LoadRequest_Params)
// The request method: GET, POST, etc.
IPC_STRUCT_MEMBER(std::string, method)
// The requested URL.
IPC_STRUCT_MEMBER(GURL, url)
// The URL to send in the "Referer" header field. Can be empty if there is
// no referrer.
IPC_STRUCT_MEMBER(GURL, referrer)
// One of the WebKit::WebReferrerPolicy values.
IPC_STRUCT_MEMBER(int, referrer_policy)
// Identifies the frame within the RenderView that sent the request.
// -1 if unknown / invalid.
IPC_STRUCT_MEMBER(int64, frame_id)
// Usually the URL of the document in the top-level window, which may be
// checked by the third-party cookie blocking policy. Leaving it empty may
// lead to undesired cookie blocking. Third-party cookie blocking can be
// bypassed by setting first_party_for_cookies = url, but this should ideally
// only be done if there really is no way to determine the correct value.
IPC_STRUCT_MEMBER(GURL, first_party_for_cookies)
// Additional HTTP request headers.
IPC_STRUCT_MEMBER(std::string, headers)
// net::URLRequest load flags (0 by default).
IPC_STRUCT_MEMBER(int, load_flags)
// Optional upload data (may be null).
IPC_STRUCT_MEMBER(scoped_refptr<net::UploadData>, upload_data)
IPC_STRUCT_END()
// Tell the renderer to load a request.
IPC_MESSAGE_ROUTED1(CefMsg_LoadRequest,
CefMsg_LoadRequest_Params)
// Sent when the browser has a request for the renderer. The renderer may
// respond with a CefHostMsg_Response.
IPC_MESSAGE_ROUTED1(CefMsg_Request,
Cef_Request_Params)
// Optional message sent in response to a CefHostMsg_Request.
IPC_MESSAGE_ROUTED1(CefMsg_Response,
Cef_Response_Params)
// Optional Ack message sent to the browser to notify that a CefHostMsg_Response
// has been processed.
IPC_MESSAGE_ROUTED1(CefMsg_ResponseAck,
int /* request_id */)
// Sent to child processes to register a scheme.
IPC_MESSAGE_CONTROL4(CefProcessMsg_RegisterScheme,
std::string /* sheme_name */,
bool /* is_standard */,
bool /* is_local */,
bool /* is_display_isolated */)
// Sent to child processes to add or remove a cross-origin whitelist entry.
IPC_MESSAGE_CONTROL5(CefProcessMsg_ModifyCrossOriginWhitelistEntry,
bool /* add */,
std::string /* source_origin */,
std::string /* target_protocol */,
std::string /* target_domain */,
bool /* allow_target_subdomains */)
// Sent to child processes to clear the cross-origin whitelist.
IPC_MESSAGE_CONTROL0(CefProcessMsg_ClearCrossOriginWhitelist)
// Messages sent from the renderer to the browser.
// Sent when the render thread has started and all filters are attached.
IPC_MESSAGE_CONTROL0(CefProcessHostMsg_RenderThreadStarted)
// Sent when a frame is identified for the first time.
IPC_MESSAGE_ROUTED3(CefHostMsg_FrameIdentified,
int64 /* frame_id */,
int64 /* parent_frame_id */,
string16 /* frame_name */)
// Sent when a frame has been detached.
IPC_MESSAGE_ROUTED1(CefHostMsg_FrameDetached,
int64 /* frame_id */)
// Sent when a new frame has been given focus.
IPC_MESSAGE_ROUTED1(CefHostMsg_FrameFocusChange,
int64 /* frame_id */)
// Sent when a new URL is about to be loaded in the main frame. Used for the
// cookie manager.
IPC_MESSAGE_ROUTED1(CefHostMsg_LoadingURLChange,
GURL /* loading_url */)
// Sent when the renderer has a request for the browser. The browser may respond
// with a CefMsg_Response.
IPC_MESSAGE_ROUTED1(CefHostMsg_Request,
Cef_Request_Params)
// Optional message sent in response to a CefMsg_Request.
IPC_MESSAGE_ROUTED1(CefHostMsg_Response,
Cef_Response_Params)
// Optional Ack message sent to the browser to notify that a CefMsg_Response
// has been processed.
IPC_MESSAGE_ROUTED1(CefHostMsg_ResponseAck,
int /* request_id */)

View File

@@ -0,0 +1,24 @@
// 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/common/cef_switches.h"
namespace switches {
// Product version string.
const char kProductVersion[] = "product-version";
// Locale string.
const char kLocale[] = "locale";
// Path to cef.pak file.
const char kPackFilePath[] = "pack-file-path";
// Path to locales directory.
const char kLocalesDirPath[] = "locales-dir-path";
// Path to locales directory.
const char kPackLoadingDisabled[] = "pack-loading-disabled";
} // namespace switches

View File

@@ -0,0 +1,21 @@
// 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.
// Defines all the "cef" command-line switches.
#ifndef CEF_LIBCEF_COMMON_CEF_SWITCHES_H_
#define CEF_LIBCEF_COMMON_CEF_SWITCHES_H_
#pragma once
namespace switches {
extern const char kProductVersion[];
extern const char kLocale[];
extern const char kPackFilePath[];
extern const char kLocalesDirPath[];
extern const char kPackLoadingDisabled[];
} // namespace switches
#endif // CEF_LIBCEF_COMMON_CEF_SWITCHES_H_

View File

@@ -0,0 +1,146 @@
// 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/common/command_line_impl.h"
#include "base/file_path.h"
#include "base/logging.h"
CefCommandLineImpl::CefCommandLineImpl(CommandLine* value,
bool will_delete,
bool read_only)
: CefValueBase<CefCommandLine, CommandLine>(
value, NULL, will_delete ? kOwnerWillDelete : kOwnerNoDelete,
read_only, NULL) {
}
bool CefCommandLineImpl::IsValid() {
return !detached();
}
bool CefCommandLineImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefCommandLine> CefCommandLineImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return new CefCommandLineImpl(
new CommandLine(const_value().argv()), true, false);
}
void CefCommandLineImpl::InitFromArgv(int argc, const char* const* argv) {
#if !defined(OS_WIN)
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->InitFromArgv(argc, argv);
#else
NOTREACHED() << "method not supported on this platform";
#endif
}
void CefCommandLineImpl::InitFromString(const CefString& command_line) {
#if defined(OS_WIN)
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->ParseFromString(command_line);
#else
NOTREACHED() << "method not supported on this platform";
#endif
}
void CefCommandLineImpl::Reset() {
CEF_VALUE_VERIFY_RETURN_VOID(true);
CommandLine::StringVector argv;
argv.push_back(mutable_value()->GetProgram().value());
mutable_value()->InitFromArgv(argv);
const CommandLine::SwitchMap& map = mutable_value()->GetSwitches();
const_cast<CommandLine::SwitchMap*>(&map)->clear();
}
CefString CefCommandLineImpl::GetCommandLineString() {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().GetCommandLineString();
}
CefString CefCommandLineImpl::GetProgram() {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().GetProgram().value();
}
void CefCommandLineImpl::SetProgram(const CefString& program) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->SetProgram(FilePath(program));
}
bool CefCommandLineImpl::HasSwitches() {
CEF_VALUE_VERIFY_RETURN(false, false);
return (const_value().GetSwitches().size() > 0);
}
bool CefCommandLineImpl::HasSwitch(const CefString& name) {
CEF_VALUE_VERIFY_RETURN(false, false);
return const_value().HasSwitch(name);
}
CefString CefCommandLineImpl::GetSwitchValue(const CefString& name) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().GetSwitchValueNative(name);
}
void CefCommandLineImpl::GetSwitches(SwitchMap& switches) {
CEF_VALUE_VERIFY_RETURN_VOID(false);
const CommandLine::SwitchMap& map = const_value().GetSwitches();
CommandLine::SwitchMap::const_iterator it = map.begin();
for (; it != map.end(); ++it)
switches.insert(std::make_pair(it->first, it->second));
}
void CefCommandLineImpl::AppendSwitch(const CefString& name) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->AppendSwitch(name);
}
void CefCommandLineImpl::AppendSwitchWithValue(const CefString& name,
const CefString& value) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->AppendSwitchNative(name, value);
}
bool CefCommandLineImpl::HasArguments() {
CEF_VALUE_VERIFY_RETURN(false, false);
return (const_value().GetArgs().size() > 0);
}
void CefCommandLineImpl::GetArguments(ArgumentList& arguments) {
CEF_VALUE_VERIFY_RETURN_VOID(false);
const CommandLine::StringVector& vec = const_value().GetArgs();
CommandLine::StringVector::const_iterator it = vec.begin();
for (; it != vec.end(); ++it)
arguments.push_back(*it);
}
void CefCommandLineImpl::AppendArgument(const CefString& argument) {
CEF_VALUE_VERIFY_RETURN_VOID(true);
mutable_value()->AppendArgNative(argument);
}
// CefCommandLine implementation.
// static
CefRefPtr<CefCommandLine> CefCommandLine::CreateCommandLine() {
return new CefCommandLineImpl(
new CommandLine(CommandLine::NO_PROGRAM), true, false);
}
// static
CefRefPtr<CefCommandLine> CefCommandLine::GetGlobalCommandLine() {
// Uses a singleton reference object.
static CefRefPtr<CefCommandLineImpl> commandLinePtr;
if (!commandLinePtr.get()) {
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line)
commandLinePtr = new CefCommandLineImpl(command_line, false, true);
}
return commandLinePtr.get();
}

View File

@@ -0,0 +1,45 @@
// 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_COMMON_COMMAND_LINE_IMPL_H_
#define CEF_LIBCEF_COMMON_COMMAND_LINE_IMPL_H_
#pragma once
#include "include/cef_command_line.h"
#include "libcef/common/value_base.h"
#include "base/command_line.h"
// CefCommandLine implementation
class CefCommandLineImpl : public CefValueBase<CefCommandLine, CommandLine> {
public:
CefCommandLineImpl(CommandLine* value,
bool will_delete,
bool read_only);
// CefCommandLine methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefCommandLine> Copy() OVERRIDE;
virtual void InitFromArgv(int argc, const char* const* argv) OVERRIDE;
virtual void InitFromString(const CefString& command_line) OVERRIDE;
virtual void Reset() OVERRIDE;
virtual CefString GetCommandLineString() OVERRIDE;
virtual CefString GetProgram() OVERRIDE;
virtual void SetProgram(const CefString& program) OVERRIDE;
virtual bool HasSwitches() OVERRIDE;
virtual bool HasSwitch(const CefString& name) OVERRIDE;
virtual CefString GetSwitchValue(const CefString& name) OVERRIDE;
virtual void GetSwitches(SwitchMap& switches) OVERRIDE;
virtual void AppendSwitch(const CefString& name) OVERRIDE;
virtual void AppendSwitchWithValue(const CefString& name,
const CefString& value) OVERRIDE;
virtual bool HasArguments() OVERRIDE;
virtual void GetArguments(ArgumentList& arguments) OVERRIDE;
virtual void AppendArgument(const CefString& argument) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(CefCommandLineImpl);
};
#endif // CEF_LIBCEF_COMMON_COMMAND_LINE_IMPL_H_

View File

@@ -0,0 +1,135 @@
// 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/common/content_client.h"
#include "include/cef_stream.h"
#include "include/cef_version.h"
#include "libcef/common/cef_switches.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_piece.h"
#include "base/stringprintf.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/user_agent.h"
CefContentClient::CefContentClient(CefRefPtr<CefApp> application)
: application_(application),
pack_loading_disabled_(false) {
}
CefContentClient::~CefContentClient() {
}
// static
CefContentClient* CefContentClient::Get() {
return static_cast<CefContentClient*>(content::GetContentClient());
}
void CefContentClient::SetActiveURL(const GURL& url) {
}
void CefContentClient::SetGpuInfo(const content::GPUInfo& gpu_info) {
}
void CefContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
}
void CefContentClient::AddNPAPIPlugins(
webkit::npapi::PluginList* plugin_list) {
}
bool CefContentClient::HasWebUIScheme(const GURL& url) const {
// There are no WebUI URLs in CEF.
return false;
}
bool CefContentClient::CanHandleWhileSwappedOut(const IPC::Message& msg) {
return false;
}
std::string CefContentClient::GetUserAgent(bool* overriding) const {
static CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kUserAgent)) {
*overriding = true;
return command_line.GetSwitchValueASCII(switches::kUserAgent);
} else {
std::string product_version;
if (command_line.HasSwitch(switches::kProductVersion)) {
*overriding = true;
product_version =
command_line.GetSwitchValueASCII(switches::kProductVersion);
} else {
*overriding = false;
product_version = base::StringPrintf("Chrome/%d.%d.%d.%d",
CHROME_VERSION_MAJOR, CHROME_VERSION_MINOR, CHROME_VERSION_BUILD,
CHROME_VERSION_PATCH);
}
return webkit_glue::BuildUserAgentFromProduct(product_version);
}
}
string16 CefContentClient::GetLocalizedString(int message_id) const {
string16 value;
if (application_.get()) {
CefRefPtr<CefResourceBundleHandler> handler =
application_->GetResourceBundleHandler();
if (handler.get()) {
CefString cef_str;
if (handler->GetLocalizedString(message_id, cef_str))
value = cef_str;
}
}
if (value.empty() && !pack_loading_disabled_)
value = ResourceBundle::GetSharedInstance().GetLocalizedString(message_id);
if (value.empty())
LOG(ERROR) << "No localized string available for id " << message_id;
return value;
}
base::StringPiece CefContentClient::GetDataResource(int resource_id) const {
base::StringPiece value;
if (application_.get()) {
CefRefPtr<CefResourceBundleHandler> handler =
application_->GetResourceBundleHandler();
if (handler.get()) {
void* data = NULL;
size_t data_size = 0;
if (handler->GetDataResource(resource_id, data, data_size))
value = base::StringPiece(static_cast<char*>(data), data_size);
}
}
if (value.empty() && !pack_loading_disabled_)
value = ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
if (value.empty())
LOG(ERROR) << "No data resource available for id " << resource_id;
return value;
}
#if defined(OS_WIN)
bool CefContentClient::SandboxPlugin(CommandLine* command_line,
sandbox::TargetPolicy* policy) {
return false;
}
#endif
#if defined(OS_MACOSX)
bool CefContentClient::GetSandboxProfileForSandboxType(
int sandbox_type,
int* sandbox_profile_resource_id) const {
return false;
}
#endif

View File

@@ -0,0 +1,58 @@
// 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.
#ifndef CEF_LIBCEF_COMMON_CONTENT_CLIENT_H_
#define CEF_LIBCEF_COMMON_CONTENT_CLIENT_H_
#pragma once
#include <string>
#include <vector>
#include "include/cef_app.h"
#include "base/compiler_specific.h"
#include "content/public/common/content_client.h"
class CefContentClient : public content::ContentClient {
public:
explicit CefContentClient(CefRefPtr<CefApp> application);
virtual ~CefContentClient();
// Returns the singleton CefContentClient instance.
static CefContentClient* Get();
virtual void SetActiveURL(const GURL& url) OVERRIDE;
virtual void SetGpuInfo(const content::GPUInfo& gpu_info) OVERRIDE;
virtual void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) OVERRIDE;
virtual void AddNPAPIPlugins(
webkit::npapi::PluginList* plugin_list) OVERRIDE;
virtual bool HasWebUIScheme(const GURL& url) const OVERRIDE;
virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE;
virtual std::string GetUserAgent(bool* overriding) const OVERRIDE;
virtual string16 GetLocalizedString(int message_id) const OVERRIDE;
virtual base::StringPiece GetDataResource(int resource_id) const OVERRIDE;
#if defined(OS_WIN)
virtual bool SandboxPlugin(CommandLine* command_line,
sandbox::TargetPolicy* policy) OVERRIDE;
#endif
#if defined(OS_MACOSX)
virtual bool GetSandboxProfileForSandboxType(
int sandbox_type,
int* sandbox_profile_resource_id) const OVERRIDE;
#endif
CefRefPtr<CefApp> application() const { return application_; }
void set_pack_loading_disabled(bool val) { pack_loading_disabled_ = val; }
bool pack_loading_disabled() const { return pack_loading_disabled_; }
private:
CefRefPtr<CefApp> application_;
bool pack_loading_disabled_;
};
#endif // CEF_LIBCEF_COMMON_CONTENT_CLIENT_H_

View File

@@ -0,0 +1,43 @@
// Copyright (c) 2011 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/common/http_header_utils.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
using net::HttpResponseHeaders;
namespace HttpHeaderUtils {
std::string GenerateHeaders(const HeaderMap& map) {
std::string headers;
for (HeaderMap::const_iterator header = map.begin();
header != map.end();
++header) {
const CefString& key = header->first;
const CefString& value = header->second;
if (!key.empty()) {
// Delimit with "\r\n".
if (!headers.empty())
headers += "\r\n";
headers += std::string(key) + ": " + std::string(value);
}
}
return headers;
}
void ParseHeaders(const std::string& header_str, HeaderMap& map) {
// Parse the request header values
for (net::HttpUtil::HeadersIterator i(header_str.begin(),
header_str.end(), "\n");
i.GetNext(); ) {
map.insert(std::make_pair(i.name(), i.values()));
}
}
} // namespace HttpHeaderUtils

View File

@@ -0,0 +1,22 @@
// 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_COMMON_HTTP_HEADER_UTILS_H_
#define CEF_LIBCEF_COMMON_HTTP_HEADER_UTILS_H_
#pragma once
#include <string>
#include "include/cef_request.h"
namespace HttpHeaderUtils {
typedef CefRequest::HeaderMap HeaderMap;
std::string GenerateHeaders(const HeaderMap& map);
void ParseHeaders(const std::string& header_str, HeaderMap& map);
}; // namespace HttpHeaderUtils
#endif // CEF_LIBCEF_COMMON_HTTP_HEADER_UTILS_H_

View File

@@ -0,0 +1,311 @@
// 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/common/main_delegate.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
#include "libcef/plugin/content_plugin_client.h"
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/utility/content_utility_client.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#if defined(OS_MACOSX)
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "content/public/common/content_paths.h"
namespace {
FilePath GetFrameworksPath() {
// Start out with the path to the running executable.
FilePath path;
PathService::Get(base::FILE_EXE, &path);
// Up to Contents.
if (base::mac::IsBackgroundOnlyProcess()) {
// The running executable is the helper. Go up five steps:
// Contents/Frameworks/Helper.app/Contents/MacOS/Helper
// ^ to here ^ from here
path = path.DirName().DirName().DirName().DirName().DirName();
} else {
// One step up to MacOS, another to Contents.
path = path.DirName().DirName();
}
DCHECK_EQ(path.BaseName().value(), "Contents");
// Go into the frameworks directory.
return path.Append("Frameworks");
}
// The framework bundle path is used for loading resources, libraries, etc.
void OverrideFrameworkBundlePath() {
FilePath helper_path =
GetFrameworksPath().Append("Chromium Embedded Framework.framework");
base::mac::SetOverrideFrameworkBundlePath(helper_path);
}
void OverrideChildProcessPath() {
// Retrieve the name of the running executable.
FilePath path;
PathService::Get(base::FILE_EXE, &path);
std::string name = path.BaseName().value();
FilePath helper_path = GetFrameworksPath().Append(name+" Helper.app")
.Append("Contents")
.Append("MacOS")
.Append(name+" Helper");
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
}
} // namespace
#endif // OS_MACOSX
CefMainDelegate::CefMainDelegate(CefRefPtr<CefApp> application)
: content_client_(application) {
}
CefMainDelegate::~CefMainDelegate() {
}
bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_MACOSX)
OverrideFrameworkBundlePath();
#endif
CommandLine* command_line = CommandLine::ForCurrentProcess();
std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty()) {
// In the browser process. Populate the global command-line object.
const CefSettings& settings = _Context->settings();
if (settings.command_line_args_disabled) {
// Remove any existing command-line arguments.
CommandLine::StringVector argv;
argv.push_back(command_line->GetProgram().value());
command_line->InitFromArgv(argv);
const CommandLine::SwitchMap& map = command_line->GetSwitches();
const_cast<CommandLine::SwitchMap*>(&map)->clear();
}
if (settings.single_process)
command_line->AppendSwitch(switches::kSingleProcess);
if (settings.browser_subprocess_path.length > 0) {
FilePath file_path =
FilePath(CefString(&settings.browser_subprocess_path));
if (!file_path.empty()) {
command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
file_path);
}
}
if (settings.user_agent.length > 0) {
command_line->AppendSwitchASCII(switches::kUserAgent,
CefString(&settings.user_agent));
} else if (settings.product_version.length > 0) {
command_line->AppendSwitchASCII(switches::kProductVersion,
CefString(&settings.product_version));
}
if (settings.locale.length > 0) {
command_line->AppendSwitchASCII(switches::kLocale,
CefString(&settings.locale));
}
if (settings.pack_loading_disabled) {
command_line->AppendSwitch(switches::kPackLoadingDisabled);
} else {
if (settings.pack_file_path.length > 0) {
FilePath file_path = FilePath(CefString(&settings.pack_file_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kPackFilePath, file_path);
}
if (settings.locales_dir_path.length > 0) {
FilePath file_path = FilePath(CefString(&settings.locales_dir_path));
if (!file_path.empty())
command_line->AppendSwitchPath(switches::kLocalesDirPath, file_path);
}
}
// TODO(cef): Figure out how to support the sandbox.
if (!command_line->HasSwitch(switches::kNoSandbox))
command_line->AppendSwitch(switches::kNoSandbox);
}
if (content_client_.application().get()) {
// Give the application a chance to view/modify the command line.
CefRefPtr<CefCommandLineImpl> commandLinePtr(
new CefCommandLineImpl(command_line, false, false));
content_client_.application()->OnBeforeCommandLineProcessing(
CefString(process_type), commandLinePtr.get());
commandLinePtr->Detach(NULL);
}
return false;
}
void CefMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
OverrideChildProcessPath();
#endif
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
content::SetContentClient(&content_client_);
InitializeContentClient(process_type);
if (command_line.HasSwitch(switches::kPackLoadingDisabled))
content_client_.set_pack_loading_disabled(true);
else
InitializeResourceBundle();
}
void CefMainDelegate::SandboxInitialized(const std::string& process_type) {
}
int CefMainDelegate::RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) {
if (process_type.empty()) {
// Use our own browser process runner.
browser_runner_.reset(content::BrowserMainRunner::Create());
// Initialize browser process state. Results in a call to
// CefBrowserMain::GetMainMessageLoop().
int exit_code = browser_runner_->Initialize(main_function_params);
if (exit_code >= 0)
return exit_code;
return 0;
}
return -1;
}
void CefMainDelegate::ProcessExiting(const std::string& process_type) {
if (!content_client_.pack_loading_disabled())
ResourceBundle::CleanupSharedInstance();
}
#if defined(OS_MACOSX)
bool CefMainDelegate::ProcessRegistersWithSystemProcess(
const std::string& process_type) {
return false;
}
bool CefMainDelegate::ShouldSendMachPort(const std::string& process_type) {
return false;
}
bool CefMainDelegate::DelaySandboxInitialization(
const std::string& process_type) {
return false;
}
#elif defined(OS_POSIX)
content::ZygoteForkDelegate* CefMainDelegate::ZygoteStarting() {
return NULL;
}
void CefMainDelegate::ZygoteForked() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
InitializeContentClient(process_type);
}
#endif // OS_MACOSX
void CefMainDelegate::ShutdownBrowser() {
if (browser_runner_.get()) {
browser_runner_->Shutdown();
browser_runner_.reset(NULL);
}
}
void CefMainDelegate::InitializeContentClient(
const std::string& process_type) {
if (process_type.empty()) {
browser_client_.reset(new CefContentBrowserClient);
content::GetContentClient()->set_browser(browser_client_.get());
// Single-process is an unsupported and not fully tested mode.
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kSingleProcess)) {
content::RenderProcessHost::set_run_renderer_in_process(true);
renderer_client_.reset(new CefContentRendererClient);
content::GetContentClient()->set_renderer(renderer_client_.get());
}
} else if (process_type == switches::kRendererProcess) {
renderer_client_.reset(new CefContentRendererClient);
content::GetContentClient()->set_renderer(renderer_client_.get());
} else if (process_type == switches::kPluginProcess) {
plugin_client_.reset(new CefContentPluginClient);
content::GetContentClient()->set_plugin(plugin_client_.get());
} else if (process_type == switches::kUtilityProcess) {
utility_client_.reset(new CefContentUtilityClient);
content::GetContentClient()->set_utility(utility_client_.get());
}
}
void CefMainDelegate::InitializeResourceBundle() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
FilePath pak_file, locales_dir;
if (command_line.HasSwitch(switches::kPackFilePath))
pak_file = command_line.GetSwitchValuePath(switches::kPackFilePath);
if (pak_file.empty()) {
FilePath pak_dir;
PathService::Get(base::DIR_MODULE, &pak_dir);
pak_file = pak_dir.Append(FILE_PATH_LITERAL("cef.pak"));
}
if (!pak_file.empty())
PathService::Override(ui::FILE_RESOURCES_PAK, pak_file);
if (command_line.HasSwitch(switches::kLocalesDirPath))
locales_dir = command_line.GetSwitchValuePath(switches::kLocalesDirPath);
if (!locales_dir.empty())
PathService::Override(ui::DIR_LOCALES, locales_dir);
std::string locale = command_line.GetSwitchValueASCII(switches::kLocale);
if (locale.empty())
locale = "en-US";
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstanceWithLocale(locale);
CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
#if defined(OS_WIN)
// Explicitly load cef.pak on Windows.
if (file_util::PathExists(pak_file))
ResourceBundle::AddDataPackToSharedInstance(pak_file);
else
NOTREACHED() << "Could not load cef.pak";
#endif
}

View File

@@ -0,0 +1,71 @@
// 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_COMMON_MAIN_DELEGATE_H_
#define CEF_LIBCEF_COMMON_MAIN_DELEGATE_H_
#pragma once
#include <string>
#include "libcef/common/content_client.h"
#include "include/cef_app.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/app/content_main_delegate.h"
namespace content {
class BrowserMainRunner;
}
class CefContentBrowserClient;
class CefContentRendererClient;
class CefContentPluginClient;
class CefContentUtilityClient;
class MessageLoop;
class CefMainDelegate : public content::ContentMainDelegate {
public:
explicit CefMainDelegate(CefRefPtr<CefApp> application);
virtual ~CefMainDelegate();
virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
virtual void PreSandboxStartup() OVERRIDE;
virtual void SandboxInitialized(const std::string& process_type) OVERRIDE;
virtual int RunProcess(
const std::string& process_type,
const content::MainFunctionParams& main_function_params) OVERRIDE;
virtual void ProcessExiting(const std::string& process_type) OVERRIDE;
#if defined(OS_MACOSX)
virtual bool ProcessRegistersWithSystemProcess(
const std::string& process_type) OVERRIDE;
virtual bool ShouldSendMachPort(const std::string& process_type) OVERRIDE;
virtual bool DelaySandboxInitialization(
const std::string& process_type) OVERRIDE;
#elif defined(OS_POSIX)
virtual content::ZygoteForkDelegate* ZygoteStarting() OVERRIDE;
virtual void ZygoteForked() OVERRIDE;
#endif // OS_MACOSX
// Shut down the browser runner.
void ShutdownBrowser();
CefContentBrowserClient* browser_client() { return browser_client_.get(); }
CefContentClient* content_client() { return &content_client_; }
private:
void InitializeContentClient(const std::string& process_type);
void InitializeResourceBundle();
scoped_ptr<content::BrowserMainRunner> browser_runner_;
scoped_ptr<CefContentBrowserClient> browser_client_;
scoped_ptr<CefContentRendererClient> renderer_client_;
scoped_ptr<CefContentPluginClient> plugin_client_;
scoped_ptr<CefContentUtilityClient> utility_client_;
CefContentClient content_client_;
DISALLOW_COPY_AND_ASSIGN(CefMainDelegate);
};
#endif // CEF_LIBCEF_COMMON_MAIN_DELEGATE_H_

View File

@@ -0,0 +1,76 @@
// 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/common/process_message_impl.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/values_impl.h"
#include "base/logging.h"
namespace {
void CopyList(const base::ListValue& source,
base::ListValue& target) {
base::ListValue::const_iterator it = source.begin();
for (; it != source.end(); ++it)
target.Append((*it)->DeepCopy());
}
void CopyValue(const Cef_Request_Params& source,
Cef_Request_Params& target) {
target.name = source.name;
CopyList(source.arguments, target.arguments);
}
} // namespace
// static
CefRefPtr<CefProcessMessage> CefProcessMessage::Create(const CefString& name) {
Cef_Request_Params* params = new Cef_Request_Params();
params->name = name;
return new CefProcessMessageImpl(params, true, false);
}
CefProcessMessageImpl::CefProcessMessageImpl(Cef_Request_Params* value,
bool will_delete,
bool read_only)
: CefValueBase<CefProcessMessage, Cef_Request_Params>(
value, NULL, will_delete ? kOwnerWillDelete : kOwnerNoDelete,
read_only, NULL) {
}
bool CefProcessMessageImpl::CopyTo(Cef_Request_Params& target) {
CEF_VALUE_VERIFY_RETURN(false, false);
CopyValue(const_value(), target);
return true;
}
bool CefProcessMessageImpl::IsValid() {
return !detached();
}
bool CefProcessMessageImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefProcessMessage> CefProcessMessageImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
Cef_Request_Params* params = new Cef_Request_Params();
CopyValue(const_value(), *params);
return new CefProcessMessageImpl(params, true, false);
}
CefString CefProcessMessageImpl::GetName() {
CEF_VALUE_VERIFY_RETURN(false, CefString());
return const_value().name;
}
CefRefPtr<CefListValue> CefProcessMessageImpl::GetArgumentList() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return CefListValueImpl::GetOrCreateRef(
const_cast<base::ListValue*>(&(const_value().arguments)),
const_cast<Cef_Request_Params*>(&const_value()),
read_only(),
controller());
}

View File

@@ -0,0 +1,35 @@
// 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_COMMON_PROCESS_MESSAGE_IMPL_H_
#define CEF_LIBCEF_COMMON_PROCESS_MESSAGE_IMPL_H_
#pragma once
#include "include/cef_process_message.h"
#include "libcef/common/value_base.h"
struct Cef_Request_Params;
// CefProcessMessage implementation
class CefProcessMessageImpl
: public CefValueBase<CefProcessMessage, Cef_Request_Params> {
public:
CefProcessMessageImpl(Cef_Request_Params* value,
bool will_delete,
bool read_only);
// Copies the underlying value to the specified |target| structure.
bool CopyTo(Cef_Request_Params& target);
// CefProcessMessage methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefProcessMessage> Copy() OVERRIDE;
virtual CefString GetName() OVERRIDE;
virtual CefRefPtr<CefListValue> GetArgumentList() OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(CefProcessMessageImpl);
};
#endif // CEF_LIBCEF_COMMON_PROCESS_MESSAGE_IMPL_H_

View File

@@ -0,0 +1,368 @@
// Copyright (c) 2008-2009 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 <string>
#include <vector>
#include "libcef/common/http_header_utils.h"
#include "libcef/common/request_impl.h"
#include "base/logging.h"
#include "net/url_request/url_request.h"
CefRefPtr<CefRequest> CefRequest::CreateRequest() {
CefRefPtr<CefRequest> request(new CefRequestImpl());
return request;
}
CefRequestImpl::CefRequestImpl()
: method_("GET"),
flags_(WUR_FLAG_NONE) {
}
CefString CefRequestImpl::GetURL() {
AutoLock lock_scope(this);
return url_;
}
void CefRequestImpl::SetURL(const CefString& url) {
AutoLock lock_scope(this);
url_ = url;
}
CefString CefRequestImpl::GetMethod() {
AutoLock lock_scope(this);
return method_;
}
void CefRequestImpl::SetMethod(const CefString& method) {
AutoLock lock_scope(this);
method_ = method;
}
CefRefPtr<CefPostData> CefRequestImpl::GetPostData() {
AutoLock lock_scope(this);
return postdata_;
}
void CefRequestImpl::SetPostData(CefRefPtr<CefPostData> postData) {
AutoLock lock_scope(this);
postdata_ = postData;
}
void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap) {
AutoLock lock_scope(this);
headerMap = headermap_;
}
void CefRequestImpl::SetHeaderMap(const HeaderMap& headerMap) {
AutoLock lock_scope(this);
headermap_ = headerMap;
}
void CefRequestImpl::Set(const CefString& url,
const CefString& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap) {
AutoLock lock_scope(this);
url_ = url;
method_ = method;
postdata_ = postData;
headermap_ = headerMap;
}
#define SETBOOLFLAG(obj, flags, method, FLAG) \
obj.method((flags & (FLAG)) == (FLAG))
CefRequest::RequestFlags CefRequestImpl::GetFlags() {
AutoLock lock_scope(this);
return flags_;
}
void CefRequestImpl::SetFlags(RequestFlags flags) {
AutoLock lock_scope(this);
flags_ = flags;
}
CefString CefRequestImpl::GetFirstPartyForCookies() {
AutoLock lock_scope(this);
return first_party_for_cookies_;
}
void CefRequestImpl::SetFirstPartyForCookies(const CefString& url) {
AutoLock lock_scope(this);
first_party_for_cookies_ = url;
}
void CefRequestImpl::Set(net::URLRequest* request) {
AutoLock lock_scope(this);
url_ = request->url().spec();
method_ = request->method();
first_party_for_cookies_ = request->first_party_for_cookies().spec();
net::HttpRequestHeaders headers = request->extra_request_headers();
// Ensure that we do not send username and password fields in the referrer.
GURL referrer(request->GetSanitizedReferrer());
// Strip Referer from request_info_.extra_headers to prevent, e.g., plugins
// from overriding headers that are controlled using other means. Otherwise a
// plugin could set a referrer although sending the referrer is inhibited.
headers.RemoveHeader(net::HttpRequestHeaders::kReferer);
// Our consumer should have made sure that this is a safe referrer. See for
// instance WebCore::FrameLoader::HideReferrer.
if (referrer.is_valid())
headers.SetHeader(net::HttpRequestHeaders::kReferer, referrer.spec());
// Transfer request headers
GetHeaderMap(headers, headermap_);
// Transfer post data, if any
net::UploadData* data = request->get_upload();
if (data) {
postdata_ = CefPostData::CreatePostData();
static_cast<CefPostDataImpl*>(postdata_.get())->Set(*data);
} else if (postdata_.get()) {
postdata_ = NULL;
}
}
void CefRequestImpl::Get(net::URLRequest* request) {
AutoLock lock_scope(this);
request->set_method(method_);
if (!first_party_for_cookies_.empty()) {
request->set_first_party_for_cookies(
GURL(std::string(first_party_for_cookies_)));
}
CefString referrerStr;
referrerStr.FromASCII("Referrer");
HeaderMap headerMap = headermap_;
HeaderMap::iterator it = headerMap.find(referrerStr);
if (it == headerMap.end()) {
request->set_referrer("");
} else {
request->set_referrer(it->second);
headerMap.erase(it);
}
net::HttpRequestHeaders headers;
headers.AddHeadersFromString(HttpHeaderUtils::GenerateHeaders(headerMap));
request->SetExtraRequestHeaders(headers);
if (postdata_.get()) {
net::UploadData* upload = new net::UploadData();
static_cast<CefPostDataImpl*>(postdata_.get())->Get(*upload);
request->set_upload(upload);
} else if (request->get_upload()) {
request->set_upload(NULL);
}
}
// static
void CefRequestImpl::GetHeaderMap(const net::HttpRequestHeaders& headers,
HeaderMap& map) {
net::HttpRequestHeaders::Iterator it(headers);
do {
map.insert(std::make_pair(it.name(), it.value()));
} while (it.GetNext());
}
CefRefPtr<CefPostData> CefPostData::CreatePostData() {
CefRefPtr<CefPostData> postdata(new CefPostDataImpl());
return postdata;
}
CefPostDataImpl::CefPostDataImpl() {
}
size_t CefPostDataImpl::GetElementCount() {
AutoLock lock_scope(this);
return elements_.size();
}
void CefPostDataImpl::GetElements(ElementVector& elements) {
AutoLock lock_scope(this);
elements = elements_;
}
bool CefPostDataImpl::RemoveElement(CefRefPtr<CefPostDataElement> element) {
AutoLock lock_scope(this);
ElementVector::iterator it = elements_.begin();
for (; it != elements_.end(); ++it) {
if (it->get() == element.get()) {
elements_.erase(it);
return true;
}
}
return false;
}
bool CefPostDataImpl::AddElement(CefRefPtr<CefPostDataElement> element) {
bool found = false;
AutoLock lock_scope(this);
// check that the element isn't already in the list before adding
ElementVector::const_iterator it = elements_.begin();
for (; it != elements_.end(); ++it) {
if (it->get() == element.get()) {
found = true;
break;
}
}
if (!found)
elements_.push_back(element);
return !found;
}
void CefPostDataImpl::RemoveElements() {
AutoLock lock_scope(this);
elements_.clear();
}
void CefPostDataImpl::Set(net::UploadData& data) {
AutoLock lock_scope(this);
CefRefPtr<CefPostDataElement> postelem;
std::vector<net::UploadData::Element>* elements = data.elements();
std::vector<net::UploadData::Element>::const_iterator it = elements->begin();
for (; it != elements->end(); ++it) {
postelem = CefPostDataElement::CreatePostDataElement();
static_cast<CefPostDataElementImpl*>(postelem.get())->Set(*it);
AddElement(postelem);
}
}
void CefPostDataImpl::Get(net::UploadData& data) {
AutoLock lock_scope(this);
net::UploadData::Element element;
std::vector<net::UploadData::Element> data_elements;
ElementVector::iterator it = elements_.begin();
for (; it != elements_.end(); ++it) {
static_cast<CefPostDataElementImpl*>(it->get())->Get(element);
data_elements.push_back(element);
}
data.SetElements(data_elements);
}
CefRefPtr<CefPostDataElement> CefPostDataElement::CreatePostDataElement() {
CefRefPtr<CefPostDataElement> element(new CefPostDataElementImpl());
return element;
}
CefPostDataElementImpl::CefPostDataElementImpl() {
type_ = PDE_TYPE_EMPTY;
memset(&data_, 0, sizeof(data_));
}
CefPostDataElementImpl::~CefPostDataElementImpl() {
SetToEmpty();
}
void CefPostDataElementImpl::SetToEmpty() {
AutoLock lock_scope(this);
if (type_ == PDE_TYPE_BYTES)
free(data_.bytes.bytes);
else if (type_ == PDE_TYPE_FILE)
cef_string_clear(&data_.filename);
type_ = PDE_TYPE_EMPTY;
memset(&data_, 0, sizeof(data_));
}
void CefPostDataElementImpl::SetToFile(const CefString& fileName) {
AutoLock lock_scope(this);
// Clear any data currently in the element
SetToEmpty();
// Assign the new data
type_ = PDE_TYPE_FILE;
cef_string_copy(fileName.c_str(), fileName.length(), &data_.filename);
}
void CefPostDataElementImpl::SetToBytes(size_t size, const void* bytes) {
AutoLock lock_scope(this);
// Clear any data currently in the element
SetToEmpty();
// Assign the new data
void* data = malloc(size);
DCHECK(data != NULL);
if (data == NULL)
return;
memcpy(data, bytes, size);
type_ = PDE_TYPE_BYTES;
data_.bytes.bytes = data;
data_.bytes.size = size;
}
CefPostDataElement::Type CefPostDataElementImpl::GetType() {
AutoLock lock_scope(this);
return type_;
}
CefString CefPostDataElementImpl::GetFile() {
AutoLock lock_scope(this);
DCHECK(type_ == PDE_TYPE_FILE);
CefString filename;
if (type_ == PDE_TYPE_FILE)
filename.FromString(data_.filename.str, data_.filename.length, false);
return filename;
}
size_t CefPostDataElementImpl::GetBytesCount() {
AutoLock lock_scope(this);
DCHECK(type_ == PDE_TYPE_BYTES);
size_t size = 0;
if (type_ == PDE_TYPE_BYTES)
size = data_.bytes.size;
return size;
}
size_t CefPostDataElementImpl::GetBytes(size_t size, void* bytes) {
AutoLock lock_scope(this);
DCHECK(type_ == PDE_TYPE_BYTES);
size_t rv = 0;
if (type_ == PDE_TYPE_BYTES) {
rv = (size < data_.bytes.size ? size : data_.bytes.size);
memcpy(bytes, data_.bytes.bytes, rv);
}
return rv;
}
void CefPostDataElementImpl::Set(const net::UploadData::Element& element) {
AutoLock lock_scope(this);
if (element.type() == net::UploadData::TYPE_BYTES) {
SetToBytes(element.bytes().size(),
static_cast<const void*>(
std::string(element.bytes().begin(),
element.bytes().end()).c_str()));
} else if (element.type() == net::UploadData::TYPE_FILE) {
SetToFile(element.file_path().value());
} else {
NOTREACHED();
}
}
void CefPostDataElementImpl::Get(net::UploadData::Element& element) {
AutoLock lock_scope(this);
if (type_ == PDE_TYPE_BYTES) {
element.SetToBytes(static_cast<char*>(data_.bytes.bytes), data_.bytes.size);
} else if (type_ == PDE_TYPE_FILE) {
FilePath path = FilePath(CefString(&data_.filename));
element.SetToFilePath(path);
} else {
NOTREACHED();
}
}

View File

@@ -0,0 +1,118 @@
// 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_COMMON_REQUEST_IMPL_H_
#define CEF_LIBCEF_COMMON_REQUEST_IMPL_H_
#pragma once
#include "include/cef_request.h"
#include "net/base/upload_data.h"
#include "net/http/http_request_headers.h"
namespace net {
class URLRequest;
};
// Implementation of CefRequest
class CefRequestImpl : public CefRequest {
public:
CefRequestImpl();
~CefRequestImpl() {}
virtual CefString GetURL() OVERRIDE;
virtual void SetURL(const CefString& url) OVERRIDE;
virtual CefString GetMethod() OVERRIDE;
virtual void SetMethod(const CefString& method) OVERRIDE;
virtual CefRefPtr<CefPostData> GetPostData() OVERRIDE;
virtual void SetPostData(CefRefPtr<CefPostData> postData) OVERRIDE;
virtual void GetHeaderMap(HeaderMap& headerMap) OVERRIDE;
virtual void SetHeaderMap(const HeaderMap& headerMap) OVERRIDE;
virtual void Set(const CefString& url,
const CefString& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap) OVERRIDE;
virtual RequestFlags GetFlags() OVERRIDE;
virtual void SetFlags(RequestFlags flags) OVERRIDE;
virtual CefString GetFirstPartyForCookies() OVERRIDE;
virtual void SetFirstPartyForCookies(const CefString& url) OVERRIDE;
// Populate this object from the URLRequest object.
void Set(net::URLRequest* request);
// Populate the URLRequest object from this object.
void Get(net::URLRequest* request);
static void GetHeaderMap(const net::HttpRequestHeaders& headers,
HeaderMap& map);
protected:
CefString url_;
CefString method_;
CefRefPtr<CefPostData> postdata_;
HeaderMap headermap_;
// The below methods are used by WebURLRequest.
RequestFlags flags_;
CefString first_party_for_cookies_;
IMPLEMENT_REFCOUNTING(CefRequestImpl);
IMPLEMENT_LOCKING(CefRequestImpl);
};
// Implementation of CefPostData
class CefPostDataImpl : public CefPostData {
public:
CefPostDataImpl();
~CefPostDataImpl() {}
virtual size_t GetElementCount() OVERRIDE;
virtual void GetElements(ElementVector& elements) OVERRIDE;
virtual bool RemoveElement(CefRefPtr<CefPostDataElement> element) OVERRIDE;
virtual bool AddElement(CefRefPtr<CefPostDataElement> element) OVERRIDE;
virtual void RemoveElements();
void Set(net::UploadData& data);
void Get(net::UploadData& data);
protected:
ElementVector elements_;
IMPLEMENT_REFCOUNTING(CefPostDataImpl);
IMPLEMENT_LOCKING(CefPostDataImpl);
};
// Implementation of CefPostDataElement
class CefPostDataElementImpl : public CefPostDataElement {
public:
CefPostDataElementImpl();
~CefPostDataElementImpl();
virtual void SetToEmpty() OVERRIDE;
virtual void SetToFile(const CefString& fileName) OVERRIDE;
virtual void SetToBytes(size_t size, const void* bytes) OVERRIDE;
virtual Type GetType() OVERRIDE;
virtual CefString GetFile() OVERRIDE;
virtual size_t GetBytesCount() OVERRIDE;
virtual size_t GetBytes(size_t size, void* bytes) OVERRIDE;
void* GetBytes() { return data_.bytes.bytes; }
void Set(const net::UploadData::Element& element);
void Get(net::UploadData::Element& element);
protected:
Type type_;
union {
struct {
void* bytes;
size_t size;
} bytes;
cef_string_t filename;
} data_;
IMPLEMENT_REFCOUNTING(CefPostDataElementImpl);
IMPLEMENT_LOCKING(CefPostDataElementImpl);
};
#endif // CEF_LIBCEF_COMMON_REQUEST_IMPL_H_

View File

@@ -0,0 +1,98 @@
// 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/common/response_impl.h"
#include "base/logging.h"
#include "base/stringprintf.h"
#include "net/http/http_response_headers.h"
CefResponseImpl::CefResponseImpl()
: status_code_(0) {
}
int CefResponseImpl::GetStatus() {
AutoLock lock_scope(this);
return status_code_;
}
void CefResponseImpl::SetStatus(int status) {
AutoLock lock_scope(this);
status_code_ = status;
}
CefString CefResponseImpl::GetStatusText() {
AutoLock lock_scope(this);
return status_text_;
}
void CefResponseImpl::SetStatusText(const CefString& statusText) {
AutoLock lock_scope(this);
status_text_ = statusText;
}
CefString CefResponseImpl::GetMimeType() {
AutoLock lock_scope(this);
return mime_type_;
}
void CefResponseImpl::SetMimeType(const CefString& mimeType) {
AutoLock lock_scope(this);
mime_type_ = mimeType;
}
CefString CefResponseImpl::GetHeader(const CefString& name) {
AutoLock lock_scope(this);
CefString value;
HeaderMap::const_iterator it = header_map_.find(name);
if (it != header_map_.end())
value = it->second;
return value;
}
void CefResponseImpl::GetHeaderMap(HeaderMap& map) {
AutoLock lock_scope(this);
map = header_map_;
}
void CefResponseImpl::SetHeaderMap(const HeaderMap& headerMap) {
AutoLock lock_scope(this);
header_map_ = headerMap;
}
net::HttpResponseHeaders* CefResponseImpl::GetResponseHeaders() {
AutoLock lock_scope(this);
std::string response;
std::string status_text;
if (status_text_.empty())
status_text = (status_code_ == 200)?"OK":"ERROR";
else
status_text = status_text_;
base::SStringPrintf(&response, "HTTP/1.1 %d %s", status_code_,
status_text.c_str());
if (header_map_.size() > 0) {
for (HeaderMap::const_iterator header = header_map_.begin();
header != header_map_.end();
++header) {
const CefString& key = header->first;
const CefString& value = header->second;
if (!key.empty()) {
// Delimit with "\0" as required by net::HttpResponseHeaders.
std::string key_str(key);
std::string value_str(value);
base::StringAppendF(&response, "%c%s: %s", '\0', key_str.c_str(),
value_str.c_str());
}
}
}
return new net::HttpResponseHeaders(response);
}

View File

@@ -0,0 +1,44 @@
// 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_COMMON_RESPONSE_IMPL_H_
#define CEF_LIBCEF_COMMON_RESPONSE_IMPL_H_
#pragma once
#include "include/cef_response.h"
namespace net {
class HttpResponseHeaders;
}
// Implementation of CefResponse.
class CefResponseImpl : public CefResponse {
public:
CefResponseImpl();
~CefResponseImpl() {}
// CefResponse API
virtual int GetStatus();
virtual void SetStatus(int status);
virtual CefString GetStatusText();
virtual void SetStatusText(const CefString& statusText);
virtual CefString GetMimeType();
virtual void SetMimeType(const CefString& mimeType);
virtual CefString GetHeader(const CefString& name);
virtual void GetHeaderMap(HeaderMap& headerMap);
virtual void SetHeaderMap(const HeaderMap& headerMap);
net::HttpResponseHeaders* GetResponseHeaders();
protected:
int status_code_;
CefString status_text_;
CefString mime_type_;
HeaderMap header_map_;
IMPLEMENT_REFCOUNTING(CefResponseImpl);
IMPLEMENT_LOCKING(CefResponseImpl);
};
#endif // CEF_LIBCEF_COMMON_RESPONSE_IMPL_H_

View File

@@ -0,0 +1,54 @@
// 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/common/response_manager.h"
#include "libcef/common/cef_messages.h"
#include "base/logging.h"
CefResponseManager::CefResponseManager()
: next_request_id_(0) {
}
int CefResponseManager::GetNextRequestId() {
DCHECK(CalledOnValidThread());
return ++next_request_id_;
}
int CefResponseManager::RegisterHandler(CefRefPtr<Handler> handler) {
DCHECK(CalledOnValidThread());
int request_id = GetNextRequestId();
handlers_.insert(std::make_pair(request_id, handler));
return request_id;
}
bool CefResponseManager::RunHandler(const Cef_Response_Params& params) {
DCHECK(CalledOnValidThread());
DCHECK_GT(params.request_id, 0);
HandlerMap::iterator it = handlers_.find(params.request_id);
if (it != handlers_.end()) {
it->second->OnResponse(params);
handlers_.erase(it);
return true;
}
return false;
}
void CefResponseManager::RegisterAckHandler(int request_id,
CefRefPtr<AckHandler> handler) {
DCHECK(CalledOnValidThread());
ack_handlers_.insert(std::make_pair(request_id, handler));
}
bool CefResponseManager::RunAckHandler(int request_id) {
DCHECK(CalledOnValidThread());
DCHECK_GT(request_id, 0);
AckHandlerMap::iterator it = ack_handlers_.find(request_id);
if (it != ack_handlers_.end()) {
it->second->OnResponseAck();
ack_handlers_.erase(it);
return true;
}
return false;
}

View File

@@ -0,0 +1,62 @@
// 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_COMMON_RESPONSE_MANAGER_H_
#define CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_
#pragma once
#include <map>
#include "include/cef_base.h"
#include "base/threading/non_thread_safe.h"
struct Cef_Response_Params;
// This class is not thread-safe.
class CefResponseManager : base::NonThreadSafe {
public:
// Used for handling response messages.
class Handler : public virtual CefBase {
public:
virtual void OnResponse(const Cef_Response_Params& params) =0;
};
// Used for handling response ack messages.
class AckHandler : public virtual CefBase {
public:
virtual void OnResponseAck() =0;
};
CefResponseManager();
// Returns the next unique request id.
int GetNextRequestId();
// Register a response handler and return the unique request id.
int RegisterHandler(CefRefPtr<Handler> handler);
// Run the response handler for the specified request id. Returns true if a
// handler was run.
bool RunHandler(const Cef_Response_Params& params);
// Register a response ack handler for the specified request id.
void RegisterAckHandler(int request_id, CefRefPtr<AckHandler> handler);
// Run the response ack handler for the specified request id. Returns true if
// a handler was run.
bool RunAckHandler(int request_id);
private:
// Used for generating unique request ids.
int next_request_id_;
// Map of unique request ids to Handler references.
typedef std::map<int, CefRefPtr<Handler> > HandlerMap;
HandlerMap handlers_;
// Map of unique request ids to AckHandler references.
typedef std::map<int, CefRefPtr<AckHandler> > AckHandlerMap;
AckHandlerMap ack_handlers_;
};
#endif // CEF_LIBCEF_COMMON_RESPONSE_MANAGER_H_

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2009 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 <vector>
#include "include/internal/cef_string_list.h"
#include "base/logging.h"
typedef std::vector<CefString> StringList;
CEF_EXPORT cef_string_list_t cef_string_list_alloc() {
return new StringList;
}
CEF_EXPORT int cef_string_list_size(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
return impl->size();
}
CEF_EXPORT int cef_string_list_value(cef_string_list_t list, int index,
cef_string_t* value) {
DCHECK(list);
DCHECK(value);
StringList* impl = reinterpret_cast<StringList*>(list);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return false;
const CefString& str = (*impl)[index];
return cef_string_copy(str.c_str(), str.length(), value);
}
CEF_EXPORT void cef_string_list_append(cef_string_list_t list,
const cef_string_t* value) {
DCHECK(list);
DCHECK(value);
StringList* impl = reinterpret_cast<StringList*>(list);
impl->push_back(CefString(value));
}
CEF_EXPORT void cef_string_list_clear(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
impl->clear();
}
CEF_EXPORT void cef_string_list_free(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
delete impl;
}
CEF_EXPORT cef_string_list_t cef_string_list_copy(cef_string_list_t list) {
DCHECK(list);
StringList* impl = reinterpret_cast<StringList*>(list);
return new StringList(*impl);
}

View File

@@ -0,0 +1,92 @@
// Copyright (c) 2009 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 <map>
#include "include/internal/cef_string_map.h"
#include "base/logging.h"
typedef std::map<CefString, CefString> StringMap;
CEF_EXPORT cef_string_map_t cef_string_map_alloc() {
return new StringMap;
}
CEF_EXPORT int cef_string_map_size(cef_string_map_t map) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
return impl->size();
}
CEF_EXPORT int cef_string_map_find(cef_string_map_t map,
const cef_string_t* key,
cef_string_t* value) {
DCHECK(map);
DCHECK(value);
StringMap* impl = reinterpret_cast<StringMap*>(map);
StringMap::const_iterator it = impl->find(CefString(key));
if (it == impl->end())
return 0;
const CefString& val = it->second;
return cef_string_set(val.c_str(), val.length(), value, true);
}
CEF_EXPORT int cef_string_map_key(cef_string_map_t map, int index,
cef_string_t* key) {
DCHECK(map);
DCHECK(key);
StringMap* impl = reinterpret_cast<StringMap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index)
return cef_string_set(it->first.c_str(), it->first.length(), key, true);
}
return 0;
}
CEF_EXPORT int cef_string_map_value(cef_string_map_t map, int index,
cef_string_t* value) {
DCHECK(map);
DCHECK(value);
StringMap* impl = reinterpret_cast<StringMap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index) {
return cef_string_set(it->second.c_str(), it->second.length(), value,
true);
}
}
return 0;
}
CEF_EXPORT int cef_string_map_append(cef_string_map_t map,
const cef_string_t* key,
const cef_string_t* value) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
impl->insert(std::make_pair(CefString(key), CefString(value)));
return 1;
}
CEF_EXPORT void cef_string_map_clear(cef_string_map_t map) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
impl->clear();
}
CEF_EXPORT void cef_string_map_free(cef_string_map_t map) {
DCHECK(map);
StringMap* impl = reinterpret_cast<StringMap*>(map);
delete impl;
}

View File

@@ -0,0 +1,116 @@
// 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 <map>
#include "include/internal/cef_string_multimap.h"
#include "base/logging.h"
typedef std::multimap<CefString, CefString> StringMultimap;
CEF_EXPORT cef_string_multimap_t cef_string_multimap_alloc() {
return new StringMultimap;
}
CEF_EXPORT int cef_string_multimap_size(cef_string_multimap_t map) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
return impl->size();
}
CEF_EXPORT int cef_string_multimap_find_count(cef_string_multimap_t map,
const cef_string_t* key) {
DCHECK(map);
DCHECK(key);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
return impl->count(CefString(key));
}
CEF_EXPORT int cef_string_multimap_enumerate(cef_string_multimap_t map,
const cef_string_t* key,
int value_index,
cef_string_t* value) {
DCHECK(map);
DCHECK(key);
DCHECK(value);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
CefString key_str(key);
DCHECK_GE(value_index, 0);
DCHECK_LT(value_index, static_cast<int>(impl->count(key_str)));
if (value_index < 0 || value_index >= static_cast<int>(impl->count(key_str)))
return 0;
std::pair<StringMultimap::iterator, StringMultimap::iterator> range_it =
impl->equal_range(key_str);
int count = value_index;
while (count-- && range_it.first != range_it.second)
range_it.first++;
if (range_it.first == range_it.second)
return 0;
const CefString& val = range_it.first->second;
return cef_string_set(val.c_str(), val.length(), value, true);
}
CEF_EXPORT int cef_string_multimap_key(cef_string_multimap_t map, int index,
cef_string_t* key) {
DCHECK(map);
DCHECK(key);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMultimap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index)
return cef_string_set(it->first.c_str(), it->first.length(), key, true);
}
return 0;
}
CEF_EXPORT int cef_string_multimap_value(cef_string_multimap_t map, int index,
cef_string_t* value) {
DCHECK(map);
DCHECK(value);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(impl->size()));
if (index < 0 || index >= static_cast<int>(impl->size()))
return 0;
StringMultimap::const_iterator it = impl->begin();
for (int ct = 0; it != impl->end(); ++it, ct++) {
if (ct == index) {
return cef_string_set(it->second.c_str(), it->second.length(), value,
true);
}
}
return 0;
}
CEF_EXPORT int cef_string_multimap_append(cef_string_multimap_t map,
const cef_string_t* key,
const cef_string_t* value) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
impl->insert(std::make_pair(CefString(key), CefString(value)));
return 1;
}
CEF_EXPORT void cef_string_multimap_clear(cef_string_multimap_t map) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
impl->clear();
}
CEF_EXPORT void cef_string_multimap_free(cef_string_multimap_t map) {
DCHECK(map);
StringMultimap* impl = reinterpret_cast<StringMultimap*>(map);
delete impl;
}

View File

@@ -0,0 +1,269 @@
// Copyright (c) 2010 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 "include/internal/cef_string_types.h"
#include "base/logging.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
namespace {
void string_wide_dtor(wchar_t* str) {
delete [] str;
}
void string_utf8_dtor(char* str) {
delete [] str;
}
void string_utf16_dtor(char16* str) {
delete [] str;
}
} // namespace
CEF_EXPORT int cef_string_wide_set(const wchar_t* src, size_t src_len,
cef_string_wide_t* output, int copy) {
cef_string_wide_clear(output);
if (copy) {
if (src && src_len > 0) {
output->str = new wchar_t[src_len+1];
if (!output->str)
return 0;
memcpy(output->str, src, src_len * sizeof(wchar_t));
output->str[src_len] = 0;
output->length = src_len;
output->dtor = string_wide_dtor;
}
} else {
output->str = const_cast<wchar_t*>(src);
output->length = src_len;
output->dtor = NULL;
}
return 1;
}
CEF_EXPORT int cef_string_utf8_set(const char* src, size_t src_len,
cef_string_utf8_t* output, int copy) {
cef_string_utf8_clear(output);
if (copy) {
if (src && src_len > 0) {
output->str = new char[src_len+1];
if (!output->str)
return 0;
memcpy(output->str, src, src_len * sizeof(char));
output->str[src_len] = 0;
output->length = src_len;
output->dtor = string_utf8_dtor;
}
} else {
output->str = const_cast<char*>(src);
output->length = src_len;
output->dtor = NULL;
}
return 1;
}
CEF_EXPORT int cef_string_utf16_set(const char16* src, size_t src_len,
cef_string_utf16_t* output, int copy) {
cef_string_utf16_clear(output);
if (copy) {
if (src && src_len > 0) {
output->str = new char16[src_len+1];
if (!output->str)
return 0;
memcpy(output->str, src, src_len * sizeof(char16));
output->str[src_len] = 0;
output->length = src_len;
output->dtor = string_utf16_dtor;
}
} else {
output->str = const_cast<char16*>(src);
output->length = src_len;
output->dtor = NULL;
}
return 1;
}
CEF_EXPORT void cef_string_wide_clear(cef_string_wide_t* str) {
DCHECK(str != NULL);
if (str->dtor && str->str)
str->dtor(str->str);
str->str = NULL;
str->length = 0;
str->dtor = NULL;
}
CEF_EXPORT void cef_string_utf8_clear(cef_string_utf8_t* str) {
DCHECK(str != NULL);
if (str->dtor && str->str)
str->dtor(str->str);
str->str = NULL;
str->length = 0;
str->dtor = NULL;
}
CEF_EXPORT void cef_string_utf16_clear(cef_string_utf16_t* str) {
DCHECK(str != NULL);
if (str->dtor && str->str)
str->dtor(str->str);
str->str = NULL;
str->length = 0;
str->dtor = NULL;
}
CEF_EXPORT int cef_string_wide_cmp(const cef_string_wide_t* str1,
const cef_string_wide_t* str2) {
if (str1->length == 0 && str2->length == 0)
return 0;
int r = wcsncmp(str1->str, str2->str, std::min(str1->length, str2->length));
if (r == 0) {
if (str1->length > str2->length)
return 1;
else if (str1->length < str2->length)
return -1;
}
return r;
}
CEF_EXPORT int cef_string_utf8_cmp(const cef_string_utf8_t* str1,
const cef_string_utf8_t* str2) {
if (str1->length == 0 && str2->length == 0)
return 0;
int r = strncmp(str1->str, str2->str, std::min(str1->length, str2->length));
if (r == 0) {
if (str1->length > str2->length)
return 1;
else if (str1->length < str2->length)
return -1;
}
return r;
}
CEF_EXPORT int cef_string_utf16_cmp(const cef_string_utf16_t* str1,
const cef_string_utf16_t* str2) {
if (str1->length == 0 && str2->length == 0)
return 0;
#if defined(WCHAR_T_IS_UTF32)
int r = base::c16memcmp(str1->str, str2->str, std::min(str1->length,
str2->length));
#else
int r = wcsncmp(str1->str, str2->str, std::min(str1->length, str2->length));
#endif
if (r == 0) {
if (str1->length > str2->length)
return 1;
else if (str1->length < str2->length)
return -1;
}
return r;
}
CEF_EXPORT int cef_string_wide_to_utf8(const wchar_t* src, size_t src_len,
cef_string_utf8_t* output) {
std::string str;
bool ret = WideToUTF8(src, src_len, &str);
if (!cef_string_utf8_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf8_to_wide(const char* src, size_t src_len,
cef_string_wide_t* output) {
std::wstring str;
bool ret = UTF8ToWide(src, src_len, &str);
if (!cef_string_wide_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_wide_to_utf16(const wchar_t* src, size_t src_len,
cef_string_utf16_t* output) {
string16 str;
bool ret = WideToUTF16(src, src_len, &str);
if (!cef_string_utf16_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf16_to_wide(const char16* src, size_t src_len,
cef_string_wide_t* output) {
std::wstring str;
bool ret = UTF16ToWide(src, src_len, &str);
if (!cef_string_wide_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf8_to_utf16(const char* src, size_t src_len,
cef_string_utf16_t* output) {
string16 str;
bool ret = UTF8ToUTF16(src, src_len, &str);
if (!cef_string_utf16_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_utf16_to_utf8(const char16* src, size_t src_len,
cef_string_utf8_t* output) {
std::string str;
bool ret = UTF16ToUTF8(src, src_len, &str);
if (!cef_string_utf8_set(str.c_str(), str.length(), output, true))
return false;
return ret;
}
CEF_EXPORT int cef_string_ascii_to_wide(const char* src, size_t src_len,
cef_string_wide_t* output) {
std::wstring str = ASCIIToWide(std::string(src, src_len));
return cef_string_wide_set(str.c_str(), str.length(), output, true);
}
CEF_EXPORT int cef_string_ascii_to_utf16(const char* src, size_t src_len,
cef_string_utf16_t* output) {
string16 str = ASCIIToUTF16(std::string(src, src_len));
return cef_string_utf16_set(str.c_str(), str.length(), output, true);
}
CEF_EXPORT cef_string_userfree_wide_t cef_string_userfree_wide_alloc() {
cef_string_wide_t* s = new cef_string_wide_t;
memset(s, 0, sizeof(cef_string_wide_t));
return s;
}
CEF_EXPORT cef_string_userfree_utf8_t cef_string_userfree_utf8_alloc() {
cef_string_utf8_t* s = new cef_string_utf8_t;
memset(s, 0, sizeof(cef_string_utf8_t));
return s;
}
CEF_EXPORT cef_string_userfree_utf16_t cef_string_userfree_utf16_alloc() {
cef_string_utf16_t* s = new cef_string_utf16_t;
memset(s, 0, sizeof(cef_string_utf16_t));
return s;
}
CEF_EXPORT void cef_string_userfree_wide_free(cef_string_userfree_wide_t str) {
cef_string_wide_clear(str);
delete str;
}
CEF_EXPORT void cef_string_userfree_utf8_free(cef_string_userfree_utf8_t str) {
cef_string_utf8_clear(str);
delete str;
}
CEF_EXPORT void cef_string_userfree_utf16_free(
cef_string_userfree_utf16_t str) {
cef_string_utf16_clear(str);
delete str;
}

106
libcef/common/task_impl.cc Normal file
View File

@@ -0,0 +1,106 @@
// 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 "include/cef_task.h"
#include "libcef/browser/thread_util.h"
#include "libcef/renderer/thread_util.h"
#include "base/bind.h"
using content::BrowserThread;
namespace {
const int kRenderThreadId = -1;
const int kInvalidThreadId = -10;
int GetThreadId(CefThreadId threadId) {
int id = kInvalidThreadId;
switch (threadId) {
case TID_UI:
id = BrowserThread::UI;
break;
case TID_DB:
id = BrowserThread::DB;
break;
case TID_FILE:
id = BrowserThread::FILE;
break;
case TID_FILE_USER_BLOCKING:
id = BrowserThread::FILE_USER_BLOCKING;
break;
case TID_PROCESS_LAUNCHER:
id = BrowserThread::PROCESS_LAUNCHER;
break;
case TID_CACHE:
id = BrowserThread::CACHE;
break;
case TID_IO:
id = BrowserThread::IO;
break;
case TID_RENDERER:
id = kRenderThreadId;
break;
default:
NOTREACHED() << "invalid thread id " << threadId;
return kInvalidThreadId;
};
if (id >= 0) {
// Verify that we're on the browser process.
if (content::GetContentClient()->browser())
return id;
NOTREACHED() << "called on invalid process";
} else if (id == kRenderThreadId) {
// Verify that we're on the renderer process.
if (content::GetContentClient()->renderer())
return id;
NOTREACHED() << "called on invalid process";
}
return kInvalidThreadId;
}
} // namespace
bool CefCurrentlyOn(CefThreadId threadId) {
int id = GetThreadId(threadId);
if (id >= 0) {
// Browser process.
return CEF_CURRENTLY_ON(static_cast<BrowserThread::ID>(id));
} else if (id == kRenderThreadId) {
// Renderer process.
return CEF_CURRENTLY_ON_RT();
}
return false;
}
bool CefPostTask(CefThreadId threadId, CefRefPtr<CefTask> task) {
int id = GetThreadId(threadId);
if (id >= 0) {
// Browser process.
return CEF_POST_TASK(static_cast<BrowserThread::ID>(id),
base::Bind(&CefTask::Execute, task, threadId));
} else if (id == kRenderThreadId) {
// Renderer process.
return CEF_POST_TASK_RT(base::Bind(&CefTask::Execute, task, threadId));
}
return false;
}
bool CefPostDelayedTask(CefThreadId threadId, CefRefPtr<CefTask> task,
int64 delay_ms) {
int id = GetThreadId(threadId);
if (id >= 0) {
// Browser process.
return CEF_POST_DELAYED_TASK(static_cast<BrowserThread::ID>(id),
base::Bind(&CefTask::Execute, task, threadId), delay_ms);
} else if (id == kRenderThreadId) {
// Renderer process.
return CEF_POST_DELAYED_TASK_RT(
base::Bind(&CefTask::Execute, task, threadId), delay_ms);
}
return false;
}

View File

@@ -0,0 +1,73 @@
// 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/common/time_util.h"
void cef_time_to_basetime(const cef_time_t& cef_time, base::Time& time) {
base::Time::Exploded exploded;
exploded.year = cef_time.year;
exploded.month = cef_time.month;
#if !defined(OS_MACOSX)
exploded.day_of_week = cef_time.day_of_week;
#endif
exploded.day_of_month = cef_time.day_of_month;
exploded.hour = cef_time.hour;
exploded.minute = cef_time.minute;
exploded.second = cef_time.second;
exploded.millisecond = cef_time.millisecond;
time = base::Time::FromUTCExploded(exploded);
}
void cef_time_from_basetime(const base::Time& time, cef_time_t& cef_time) {
base::Time::Exploded exploded;
time.UTCExplode(&exploded);
cef_time.year = exploded.year;
cef_time.month = exploded.month;
#if !defined(OS_MACOSX)
cef_time.day_of_week = exploded.day_of_week;
#endif
cef_time.day_of_month = exploded.day_of_month;
cef_time.hour = exploded.hour;
cef_time.minute = exploded.minute;
cef_time.second = exploded.second;
cef_time.millisecond = exploded.millisecond;
}
CEF_EXPORT int cef_time_to_timet(const cef_time_t* cef_time, time_t* time) {
if (!cef_time || !time)
return 0;
base::Time base_time;
cef_time_to_basetime(*cef_time, base_time);
*time = base_time.ToTimeT();
return 1;
}
CEF_EXPORT int cef_time_from_timet(time_t time, cef_time_t* cef_time) {
if (!cef_time)
return 0;
base::Time base_time = base::Time::FromTimeT(time);
cef_time_from_basetime(base_time, *cef_time);
return 1;
}
CEF_EXPORT int cef_time_to_doublet(const cef_time_t* cef_time, double* time) {
if (!cef_time || !time)
return 0;
base::Time base_time;
cef_time_to_basetime(*cef_time, base_time);
*time = base_time.ToDoubleT();
return 1;
}
CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time) {
if (!cef_time)
return 0;
base::Time base_time = base::Time::FromDoubleT(time);
cef_time_from_basetime(base_time, *cef_time);
return 1;
}

16
libcef/common/time_util.h Normal file
View File

@@ -0,0 +1,16 @@
// 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_COMMON_TIME_UTIL_H_
#define CEF_LIBCEF_COMMON_TIME_UTIL_H_
#pragma once
#include "include/internal/cef_time.h"
#include "base/time.h"
// Converts cef_time_t to/from a base::Time object.
void cef_time_to_basetime(const cef_time_t& cef_time, base::Time& time);
void cef_time_from_basetime(const base::Time& time, cef_time_t& cef_time);
#endif // CEF_LIBCEF_COMMON_TIME_UTIL_H_

83
libcef/common/tracker.cc Normal file
View File

@@ -0,0 +1,83 @@
// 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/common/tracker.h"
// CefTrackNode implementation.
CefTrackNode::CefTrackNode()
: track_next_(NULL),
track_prev_(NULL) {
}
CefTrackNode::~CefTrackNode() {
}
void CefTrackNode::InsertTrackPrev(CefTrackNode* object) {
if (track_prev_)
track_prev_->SetTrackNext(object);
object->SetTrackNext(this);
object->SetTrackPrev(track_prev_);
track_prev_ = object;
}
void CefTrackNode::InsertTrackNext(CefTrackNode* object) {
if (track_next_)
track_next_->SetTrackPrev(object);
object->SetTrackPrev(this);
object->SetTrackNext(track_next_);
track_next_ = object;
}
void CefTrackNode::RemoveTracking() {
if (track_next_)
track_next_->SetTrackPrev(track_prev_);
if (track_prev_)
track_prev_->SetTrackNext(track_next_);
track_next_ = NULL;
track_prev_ = NULL;
}
// CefTrackManager implementation.
CefTrackManager::CefTrackManager()
: object_count_(0) {
}
CefTrackManager::~CefTrackManager() {
DeleteAll();
}
void CefTrackManager::Add(CefTrackNode* object) {
AutoLock lock_scope(this);
if (!object->IsTracked()) {
tracker_.InsertTrackNext(object);
++object_count_;
}
}
bool CefTrackManager::Delete(CefTrackNode* object) {
AutoLock lock_scope(this);
if (object->IsTracked()) {
object->RemoveTracking();
delete object;
--object_count_;
return true;
}
return false;
}
void CefTrackManager::DeleteAll() {
AutoLock lock_scope(this);
CefTrackNode* next;
do {
next = tracker_.GetTrackNext();
if (next) {
next->RemoveTracking();
delete next;
}
} while (next != NULL);
object_count_ = 0;
}

74
libcef/common/tracker.h Normal file
View File

@@ -0,0 +1,74 @@
// 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_COMMON_TRACKER_H_
#define CEF_LIBCEF_COMMON_TRACKER_H_
#pragma once
#include "include/cef_base.h"
// Class extended by objects that must be tracked. After creating a tracked
// object you should add it to the appropriate track manager.
class CefTrackNode {
public:
CefTrackNode();
virtual ~CefTrackNode();
// Returns true if the object is currently being tracked.
inline bool IsTracked() { return (track_prev_ || track_next_); }
private:
inline CefTrackNode* GetTrackPrev() { return track_prev_; }
inline void SetTrackPrev(CefTrackNode* base) { track_prev_ = base; }
inline CefTrackNode* GetTrackNext() { return track_next_; }
inline void SetTrackNext(CefTrackNode* base) { track_next_ = base; }
// Insert a new object into the tracking list before this object.
void InsertTrackPrev(CefTrackNode* object);
// Insert a new object into the tracking list after this object.
void InsertTrackNext(CefTrackNode* object);
// Remove this object from the tracking list.
void RemoveTracking();
private:
CefTrackNode* track_next_;
CefTrackNode* track_prev_;
friend class CefTrackManager;
};
// Class used to manage tracked objects. A single instance of this class
// should be created for each intended usage. Any objects that have not been
// removed by explicit calls to the Destroy() method will be removed when the
// manager object is destroyed. A manager object can be created as either a
// member variable of another class or by using lazy initialization:
// base::LazyInstance<CefTrackManager> g_singleton = LAZY_INSTANCE_INITIALIZER;
class CefTrackManager : public CefBase {
public:
CefTrackManager();
virtual ~CefTrackManager();
// Add an object to be tracked by this manager.
void Add(CefTrackNode* object);
// Delete an object tracked by this manager.
bool Delete(CefTrackNode* object);
// Delete all objects tracked by this manager.
void DeleteAll();
// Returns the number of objects currently being tracked.
inline int GetCount() { return object_count_; }
private:
CefTrackNode tracker_;
int object_count_;
IMPLEMENT_REFCOUNTING(CefTrackManager);
IMPLEMENT_LOCKING(CefTrackManager);
};
#endif // CEF_LIBCEF_COMMON_TRACKER_H_

68
libcef/common/url_impl.cc Normal file
View File

@@ -0,0 +1,68 @@
// 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 <sstream>
#include "include/cef_url.h"
#include "googleurl/src/gurl.h"
bool CefParseURL(const CefString& url,
CefURLParts& parts) {
GURL gurl(url.ToString());
if (!gurl.is_valid())
return false;
CefString(&parts.spec).FromString(gurl.spec());
CefString(&parts.scheme).FromString(gurl.scheme());
CefString(&parts.username).FromString(gurl.username());
CefString(&parts.password).FromString(gurl.password());
CefString(&parts.host).FromString(gurl.host());
CefString(&parts.port).FromString(gurl.port());
CefString(&parts.path).FromString(gurl.path());
CefString(&parts.query).FromString(gurl.query());
return true;
}
bool CefCreateURL(const CefURLParts& parts,
CefString& url) {
std::string spec = CefString(parts.spec.str, parts.spec.length, false);
std::string scheme = CefString(parts.scheme.str, parts.scheme.length, false);
std::string username =
CefString(parts.username.str, parts.username.length, false);
std::string password =
CefString(parts.password.str, parts.password.length, false);
std::string host = CefString(parts.host.str, parts.host.length, false);
std::string port = CefString(parts.port.str, parts.port.length, false);
std::string path = CefString(parts.path.str, parts.path.length, false);
std::string query = CefString(parts.query.str, parts.query.length, false);
GURL gurl;
if (!spec.empty()) {
gurl = GURL(spec);
} else if (!scheme.empty() && !host.empty()) {
std::stringstream ss;
ss << scheme << "://";
if (!username.empty()) {
ss << username;
if (!password.empty())
ss << ":" << password;
ss << "@";
}
ss << host;
if (!port.empty())
ss << ":" << port;
if (!path.empty())
ss << path;
if (!query.empty())
ss << "?" << query;
gurl = GURL(ss.str());
}
if (gurl.is_valid()) {
url = gurl.spec();
return true;
}
return false;
}

201
libcef/common/value_base.cc Normal file
View File

@@ -0,0 +1,201 @@
// 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/common/value_base.h"
CefValueController::CefValueController()
: owner_value_(NULL),
owner_object_(NULL) {
}
CefValueController::~CefValueController() {
// Everything should already have been removed.
DCHECK(!owner_value_ && !owner_object_);
DCHECK(reference_map_.empty());
DCHECK(dependency_map_.empty());
}
void CefValueController::SetOwner(void* value, Object* object) {
DCHECK(value && object);
// Controller should already be locked.
DCHECK(locked());
// Owner should only be set once.
DCHECK(!owner_value_ && !owner_object_);
owner_value_ = value;
owner_object_ = object;
}
void CefValueController::AddReference(void* value, Object* object) {
DCHECK(value && object);
// Controller should already be locked.
DCHECK(locked());
// Controller should currently have an owner.
DCHECK(owner_value_);
// Values should only be added once.
DCHECK(reference_map_.find(value) == reference_map_.end());
DCHECK(value != owner_value_);
reference_map_.insert(std::make_pair(value, object));
}
void CefValueController::Remove(void* value, bool notify_object) {
DCHECK(value);
// Controller should already be locked.
DCHECK(locked());
// Controller should currently have an owner.
DCHECK(owner_value_);
if (value == owner_value_) {
// Should never notify when removing the owner object.
DCHECK(!notify_object);
owner_value_ = NULL;
owner_object_ = NULL;
// Remove all references.
if (reference_map_.size() > 0) {
ReferenceMap::iterator it = reference_map_.begin();
for (; it != reference_map_.end(); ++it)
it->second->OnControlRemoved();
reference_map_.clear();
}
// Remove all dependencies.
dependency_map_.clear();
} else {
ReferenceMap::iterator it = reference_map_.find(value);
if (it != reference_map_.end()) {
// Remove the reference.
if (notify_object)
it->second->OnControlRemoved();
reference_map_.erase(it);
}
}
}
CefValueController::Object* CefValueController::Get(void* value) {
DCHECK(value);
// Controller should already be locked.
DCHECK(locked());
if (value == owner_value_) {
return owner_object_;
} else {
ReferenceMap::iterator it = reference_map_.find(value);
if (it != reference_map_.end())
return it->second;
return NULL;
}
}
void CefValueController::AddDependency(void* parent, void* child) {
DCHECK(parent && child && parent != child);
// Controller should already be locked.
DCHECK(locked());
DependencyMap::iterator it = dependency_map_.find(parent);
if (it == dependency_map_.end()) {
// New set.
DependencySet set;
set.insert(child);
dependency_map_.insert(std::make_pair(parent, set));
} else if (it->second.find(child) == it->second.end()) {
// Update existing set.
it->second.insert(child);
}
}
void CefValueController::RemoveDependencies(void* value) {
DCHECK(value);
// Controller should already be locked.
DCHECK(locked());
if (dependency_map_.empty())
return;
DependencyMap::iterator it_dependency = dependency_map_.find(value);
if (it_dependency == dependency_map_.end())
return;
// Start with the set of dependencies for the current value.
DependencySet remove_set = it_dependency->second;
dependency_map_.erase(it_dependency);
DependencySet::iterator it_value;
ReferenceMap::iterator it_reference;
while (remove_set.size() > 0) {
it_value = remove_set.begin();
value = *it_value;
remove_set.erase(it_value);
// Does the current value have dependencies?
it_dependency = dependency_map_.find(value);
if (it_dependency != dependency_map_.end()) {
// Append the dependency set to the remove set.
remove_set.insert(it_dependency->second.begin(),
it_dependency->second.end());
dependency_map_.erase(it_dependency);
}
// Does the current value have a reference?
it_reference = reference_map_.find(value);
if (it_reference != reference_map_.end()) {
// Remove the reference.
it_reference->second->OnControlRemoved();
reference_map_.erase(it_reference);
}
}
}
void CefValueController::TakeFrom(CefValueController* other) {
DCHECK(other);
// Both controllers should already be locked.
DCHECK(locked());
DCHECK(other->locked());
if (!other->reference_map_.empty()) {
// Transfer references from the other to this.
ReferenceMap::iterator it = other->reference_map_.begin();
for (; it != other->reference_map_.end(); ++it) {
// References should only be added once.
DCHECK(reference_map_.find(it->first) == reference_map_.end());
reference_map_.insert(std::make_pair(it->first, it->second));
}
other->reference_map_.empty();
}
if (!other->dependency_map_.empty()) {
// Transfer dependencies from the other to this.
DependencyMap::iterator it_other = other->dependency_map_.begin();
for (; it_other != other->dependency_map_.end(); ++it_other) {
DependencyMap::iterator it_me = dependency_map_.find(it_other->first);
if (it_me == dependency_map_.end()) {
// All children are new.
dependency_map_.insert(
std::make_pair(it_other->first, it_other->second));
} else {
// Evaluate each child.
DependencySet::iterator it_other_set = it_other->second.begin();
for (; it_other_set != it_other->second.end(); ++it_other_set) {
if (it_me->second.find(*it_other_set) == it_me->second.end())
it_me->second.insert(*it_other_set);
}
}
}
}
}

411
libcef/common/value_base.h Normal file
View File

@@ -0,0 +1,411 @@
// 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_COMMON_VALUE_BASE_H_
#define CEF_LIBCEF_COMMON_VALUE_BASE_H_
#pragma once
#include <map>
#include <set>
#include "include/cef_base.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
// Controller implementation base class.
class CefValueController
: public base::RefCountedThreadSafe<CefValueController> {
public:
// Implemented by a class controlled using the access controller.
class Object {
public:
virtual ~Object() {}
// Called when the value has been removed.
virtual void OnControlRemoved() =0;
};
// Encapsulates context locking and verification logic.
class AutoLock {
public:
explicit AutoLock(CefValueController* impl)
: impl_(impl),
verified_(impl && impl->VerifyThread()) {
DCHECK(impl);
if (verified_)
impl_->lock();
}
virtual ~AutoLock() {
if (verified_)
impl_->unlock();
}
inline bool verified() { return verified_; }
private:
scoped_refptr<CefValueController> impl_;
bool verified_;
DISALLOW_COPY_AND_ASSIGN(AutoLock);
};
CefValueController();
virtual ~CefValueController();
// Returns true if this controller is thread safe.
virtual bool thread_safe() =0;
// Returns true if the current thread is allowed to access this controller.
virtual bool on_correct_thread() =0;
// Lock the controller.
virtual void lock() =0;
// Unlock the controller.
virtual void unlock() =0;
// Returns true if the controller is locked on the current thread.
virtual bool locked() =0;
// Verify that the current thread is correct for accessing the controller.
inline bool VerifyThread() {
if (!thread_safe() && !on_correct_thread()) {
// This object should only be accessed from the thread that created it.
NOTREACHED() << "object accessed from incorrect thread.";
return false;
}
return true;
}
// The controller must already be locked before calling the below methods.
// Set the owner for this controller.
void SetOwner(void* value, Object* object);
// Add a reference value and associated object.
void AddReference(void* value, Object* object);
// Remove the value. If |notify_object| is true the removed object will be
// notified. If |value| is the owner all reference objects will be removed.
// If |value| has dependencies those objects will also be removed.
void Remove(void* value, bool notify_object);
// Returns the object for the specified value.
Object* Get(void* value);
// Add a dependency between |parent| and |child|.
void AddDependency(void* parent, void* child);
// Recursively removes any dependent values.
void RemoveDependencies(void* value);
// Takes ownership of all references and dependencies currently controlled by
// |other|. The |other| controller must already be locked.
void TakeFrom(CefValueController* other);
private:
// Owner object.
void* owner_value_;
Object* owner_object_;
// Map of reference objects.
typedef std::map<void*, Object*> ReferenceMap;
ReferenceMap reference_map_;
// Map of dependency objects.
typedef std::set<void*> DependencySet;
typedef std::map<void*, DependencySet> DependencyMap;
DependencyMap dependency_map_;
DISALLOW_COPY_AND_ASSIGN(CefValueController);
};
// Thread-safe access control implementation.
class CefValueControllerThreadSafe : public CefValueController {
public:
explicit CefValueControllerThreadSafe()
: locked_thread_id_(0) {}
// CefValueController methods.
virtual bool thread_safe() OVERRIDE { return true; }
virtual bool on_correct_thread() OVERRIDE { return true; }
virtual void lock() OVERRIDE {
lock_.Acquire();
locked_thread_id_ = base::PlatformThread::CurrentId();
}
virtual void unlock() OVERRIDE {
locked_thread_id_ = 0;
lock_.Release();
}
virtual bool locked() OVERRIDE {
return (locked_thread_id_ == base::PlatformThread::CurrentId());
}
private:
base::Lock lock_;
base::PlatformThreadId locked_thread_id_;
DISALLOW_COPY_AND_ASSIGN(CefValueControllerThreadSafe);
};
// Non-thread-safe access control implementation.
class CefValueControllerNonThreadSafe : public CefValueController {
public:
explicit CefValueControllerNonThreadSafe()
: thread_id_(base::PlatformThread::CurrentId()) {}
// CefValueController methods.
virtual bool thread_safe() OVERRIDE { return false; }
virtual bool on_correct_thread() OVERRIDE {
return (thread_id_ == base::PlatformThread::CurrentId());
}
virtual void lock() OVERRIDE {}
virtual void unlock() OVERRIDE {}
virtual bool locked() OVERRIDE { return on_correct_thread(); }
private:
base::PlatformThreadId thread_id_;
DISALLOW_COPY_AND_ASSIGN(CefValueControllerNonThreadSafe);
};
// Helper macros for verifying context.
#define CEF_VALUE_VERIFY_RETURN_VOID_EX(object, modify) \
if (!VerifyAttached()) \
return; \
AutoLock auto_lock(object, modify); \
if (!auto_lock.verified()) \
return;
#define CEF_VALUE_VERIFY_RETURN_VOID(modify) \
CEF_VALUE_VERIFY_RETURN_VOID_EX(this, modify)
#define CEF_VALUE_VERIFY_RETURN_EX(object, modify, error_val) \
if (!VerifyAttached()) \
return error_val; \
AutoLock auto_lock(object, modify); \
if (!auto_lock.verified()) \
return error_val;
#define CEF_VALUE_VERIFY_RETURN(modify, error_val) \
CEF_VALUE_VERIFY_RETURN_EX(this, modify, error_val)
// Template class for implementing CEF wrappers of other types.
template<class CefType, class ValueType>
class CefValueBase : public CefType, public CefValueController::Object {
public:
// Specifies how the value will be used.
enum ValueMode {
// A reference to a value managed by an existing controller. These values
// can be safely detached but ownership should not be transferred (make a
// copy of the value instead).
kReference,
// The value has its own controller and will be deleted on destruction.
// These values can only be detached to another controller otherwise any
// references will not be properly managed.
kOwnerWillDelete,
// The value has its own controller and will not be deleted on destruction.
// This should only be used for global values or scope-limited values that
// will be explicitly detached.
kOwnerNoDelete,
};
// Create a new object.
// If |read_only| is true mutable access will not be allowed.
// If |parent_value| is non-NULL and the value mode is kReference a dependency
// will be added.
CefValueBase(ValueType* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller)
: value_(value),
value_mode_(value_mode),
read_only_(read_only),
controller_(controller) {
DCHECK(value_);
// Specifying a parent value for a non-reference doesn't make sense.
DCHECK(!(!reference() && parent_value));
if (!reference() && !controller_) {
// For owned values default to using a new multi-threaded controller.
controller_ = new CefValueControllerThreadSafe();
CefValueController::AutoLock lock_scope(controller_);
if (lock_scope.verified())
controller_->SetOwner(value_, this);
}
// A controller is required.
DCHECK(controller_);
if (reference()) {
// Register the reference with the controller.
controller_->AddReference(value_, this);
// Add a dependency on the parent value.
if (parent_value)
controller_->AddDependency(parent_value, value_);
}
}
virtual ~CefValueBase() {
if (controller_ && value_)
Delete();
}
// True if the underlying value is referenced instead of owned.
inline bool reference() const { return (value_mode_ == kReference); }
// True if the underlying value will be deleted.
inline bool will_delete() const { return (value_mode_ == kOwnerWillDelete); }
// True if access to the underlying value is read-only.
inline bool read_only() const { return read_only_; }
// True if the underlying value has been detached.
inline bool detached() { return (controller_ == NULL); }
// Returns the controller.
inline CefValueController* controller() { return controller_; }
// Deletes the underlying value.
void Delete() {
CEF_VALUE_VERIFY_RETURN_VOID(false);
// Remove the object from the controller. If this is the owner object any
// references will be detached.
controller()->Remove(value_, false);
if (will_delete()) {
// Remove any dependencies.
controller()->RemoveDependencies(value_);
// Delete the value.
DeleteValue(value_);
}
controller_ = NULL;
value_ = NULL;
}
// Detaches the underlying value and returns a pointer to it. If this is an
// owner and a |new_controller| value is specified any existing references
// will be passed to the new controller.
ValueType* Detach(CefValueController* new_controller) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
// A |new_controller| value is required for mode kOwnerWillDelete.
DCHECK(!will_delete() || new_controller);
if (new_controller && !reference()) {
// Pass any existing references and dependencies to the new controller.
// They will be removed from this controller.
new_controller->TakeFrom(controller());
}
// Remove the object from the controller. If this is the owner object any
// references will be detached.
controller()->Remove(value_, false);
controller_ = NULL;
// Return the old value.
ValueType* old_val = value_;
value_ = NULL;
return old_val;
}
// Verify that the value is attached.
inline bool VerifyAttached() {
if (detached()) {
// This object should not be accessed after being detached.
NOTREACHED() << "object accessed after being detached.";
return false;
}
return true;
}
protected:
// CefValueController::Object methods.
virtual void OnControlRemoved() {
DCHECK(controller()->locked());
// Only references should be removed in this manner.
DCHECK(reference());
controller_ = NULL;
value_ = NULL;
}
// Override to customize value deletion.
virtual void DeleteValue(ValueType* value) { delete value; }
// Returns a mutable reference to the value.
inline ValueType* mutable_value() {
DCHECK(value_);
DCHECK(!read_only_);
DCHECK(controller()->locked());
return value_;
}
// Returns a const reference to the value.
inline const ValueType& const_value() {
DCHECK(value_);
DCHECK(controller()->locked());
return *value_;
}
// Verify that the value can be accessed.
inline bool VerifyAccess(bool modify) {
// The controller must already be locked.
DCHECK(controller()->locked());
if (read_only() && modify) {
// This object cannot be modified.
NOTREACHED() << "mutation attempted on read-only object.";
return false;
}
return true;
}
// Encapsulates value locking and verification logic.
class AutoLock {
public:
explicit AutoLock(CefValueBase* impl, bool modify)
: auto_lock_(impl->controller()),
verified_(auto_lock_.verified() && impl->VerifyAccess(modify)) {
}
virtual ~AutoLock() {}
inline bool verified() { return verified_; }
private:
CefValueController::AutoLock auto_lock_;
bool verified_;
DISALLOW_COPY_AND_ASSIGN(AutoLock);
};
private:
ValueType* value_;
ValueMode value_mode_;
bool read_only_;
scoped_refptr<CefValueController> controller_;
IMPLEMENT_REFCOUNTING(CefValueBase);
DISALLOW_COPY_AND_ASSIGN(CefValueBase);
};
#endif // CEF_LIBCEF_COMMON_VALUE_BASE_H_

View File

@@ -0,0 +1,812 @@
// 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/common/values_impl.h"
#include <algorithm>
#include <vector>
// CefBinaryValueImpl implementation.
CefRefPtr<CefBinaryValue> CefBinaryValue::Create(const void* data,
size_t data_size) {
DCHECK(data);
DCHECK_GT(data_size, (size_t)0);
if (!data || data_size == 0)
return NULL;
return new CefBinaryValueImpl(static_cast<char*>(const_cast<void*>(data)),
data_size, true);
}
// static
CefRefPtr<CefBinaryValue> CefBinaryValueImpl::GetOrCreateRef(
base::BinaryValue* value,
void* parent_value,
CefValueController* controller) {
DCHECK(value);
DCHECK(parent_value);
DCHECK(controller);
CefValueController::Object* object = controller->Get(value);
if (object)
return static_cast<CefBinaryValueImpl*>(object);
return new CefBinaryValueImpl(value, parent_value,
CefBinaryValueImpl::kReference, controller);
}
base::BinaryValue* CefBinaryValueImpl::CopyValue() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return const_value().DeepCopy();
}
base::BinaryValue* CefBinaryValueImpl::CopyOrDetachValue(
CefValueController* new_controller) {
base::BinaryValue* new_value;
if (!will_delete()) {
// Copy the value.
new_value = CopyValue();
} else {
// Take ownership of the value.
new_value = Detach(new_controller);
}
DCHECK(new_value);
return new_value;
}
bool CefBinaryValueImpl::IsValid() {
return !detached();
}
bool CefBinaryValueImpl::IsOwned() {
return !will_delete();
}
CefRefPtr<CefBinaryValue> CefBinaryValueImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return new CefBinaryValueImpl(const_value().DeepCopy(), NULL,
CefBinaryValueImpl::kOwnerWillDelete, NULL);
}
size_t CefBinaryValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().GetSize();
}
size_t CefBinaryValueImpl::GetData(void* buffer,
size_t buffer_size,
size_t data_offset) {
DCHECK(buffer);
DCHECK_GT(buffer_size, (size_t)0);
if (!buffer || buffer_size == 0)
return 0;
CEF_VALUE_VERIFY_RETURN(false, 0);
size_t size = const_value().GetSize();
DCHECK_LT(data_offset, size);
if (data_offset >= size)
return 0;
size = std::min(buffer_size, size-data_offset);
const char* data = const_value().GetBuffer();
memcpy(buffer, data+data_offset, size);
return size;
}
CefBinaryValueImpl::CefBinaryValueImpl(base::BinaryValue* value,
void* parent_value,
ValueMode value_mode,
CefValueController* controller)
: CefValueBase<CefBinaryValue, base::BinaryValue>(
value, parent_value, value_mode, true, controller) {
}
CefBinaryValueImpl::CefBinaryValueImpl(char* data,
size_t data_size,
bool copy)
: CefValueBase<CefBinaryValue, base::BinaryValue>(
copy ? base::BinaryValue::CreateWithCopiedBuffer(data, data_size) :
base::BinaryValue::Create(data, data_size),
NULL, kOwnerWillDelete, true, NULL) {
}
// CefDictionaryValueImpl implementation.
// static
CefRefPtr<CefDictionaryValue> CefDictionaryValue::Create() {
return new CefDictionaryValueImpl(new base::DictionaryValue(),
NULL, CefDictionaryValueImpl::kOwnerWillDelete, false, NULL);
}
// static
CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetOrCreateRef(
base::DictionaryValue* value,
void* parent_value,
bool read_only,
CefValueController* controller) {
CefValueController::Object* object = controller->Get(value);
if (object)
return static_cast<CefDictionaryValueImpl*>(object);
return new CefDictionaryValueImpl(value, parent_value,
CefDictionaryValueImpl::kReference, read_only, controller);
}
base::DictionaryValue* CefDictionaryValueImpl::CopyValue() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return const_value().DeepCopy();
}
base::DictionaryValue* CefDictionaryValueImpl::CopyOrDetachValue(
CefValueController* new_controller) {
base::DictionaryValue* new_value;
if (!will_delete()) {
// Copy the value.
new_value = CopyValue();
} else {
// Take ownership of the value.
new_value = Detach(new_controller);
}
DCHECK(new_value);
return new_value;
}
bool CefDictionaryValueImpl::IsValid() {
return !detached();
}
bool CefDictionaryValueImpl::IsOwned() {
return !will_delete();
}
bool CefDictionaryValueImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::Copy(
bool exclude_empty_children) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::DictionaryValue* value;
if (exclude_empty_children) {
value = const_cast<base::DictionaryValue&>(
const_value()).DeepCopyWithoutEmptyChildren();
} else {
value = const_value().DeepCopy();
}
return new CefDictionaryValueImpl(value, NULL,
CefDictionaryValueImpl::kOwnerWillDelete, false, NULL);
}
size_t CefDictionaryValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().size();
}
bool CefDictionaryValueImpl::Clear() {
CEF_VALUE_VERIFY_RETURN(true, false);
// Detach any dependent values.
controller()->RemoveDependencies(mutable_value());
mutable_value()->Clear();
return true;
}
bool CefDictionaryValueImpl::HasKey(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().HasKey(key);
}
bool CefDictionaryValueImpl::GetKeys(KeyList& keys) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::DictionaryValue::key_iterator it = const_value().begin_keys();
for (; it != const_value().end_keys(); ++it)
keys.push_back(*it);
return true;
}
bool CefDictionaryValueImpl::Remove(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(true, false);
return RemoveInternal(key);
}
CefValueType CefDictionaryValueImpl::GetType(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value)) {
switch (out_value->GetType()) {
case base::Value::TYPE_NULL:
return VTYPE_NULL;
case base::Value::TYPE_BOOLEAN:
return VTYPE_BOOL;
case base::Value::TYPE_INTEGER:
return VTYPE_INT;
case base::Value::TYPE_DOUBLE:
return VTYPE_DOUBLE;
case base::Value::TYPE_STRING:
return VTYPE_STRING;
case base::Value::TYPE_BINARY:
return VTYPE_BINARY;
case base::Value::TYPE_DICTIONARY:
return VTYPE_DICTIONARY;
case base::Value::TYPE_LIST:
return VTYPE_LIST;
}
}
return VTYPE_INVALID;
}
bool CefDictionaryValueImpl::GetBool(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, false);
base::Value* out_value = NULL;
bool ret_value = false;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsBoolean(&ret_value);
return ret_value;
}
int CefDictionaryValueImpl::GetInt(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
int ret_value = 0;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsInteger(&ret_value);
return ret_value;
}
double CefDictionaryValueImpl::GetDouble(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
double ret_value = 0;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsDouble(&ret_value);
return ret_value;
}
CefString CefDictionaryValueImpl::GetString(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
base::Value* out_value = NULL;
string16 ret_value;
if (const_value().GetWithoutPathExpansion(key, &out_value))
out_value->GetAsString(&ret_value);
return ret_value;
}
CefRefPtr<CefBinaryValue> CefDictionaryValueImpl::GetBinary(
const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value) &&
out_value->IsType(base::Value::TYPE_BINARY)) {
base::BinaryValue* binary_value =
static_cast<base::BinaryValue*>(out_value);
return CefBinaryValueImpl::GetOrCreateRef(binary_value,
const_cast<base::DictionaryValue*>(&const_value()), controller());
}
return NULL;
}
CefRefPtr<CefDictionaryValue> CefDictionaryValueImpl::GetDictionary(
const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value) &&
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* dict_value =
static_cast<base::DictionaryValue*>(out_value);
return CefDictionaryValueImpl::GetOrCreateRef(
dict_value,
const_cast<base::DictionaryValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
CefRefPtr<CefListValue> CefDictionaryValueImpl::GetList(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().GetWithoutPathExpansion(key, &out_value) &&
out_value->IsType(base::Value::TYPE_LIST)) {
base::ListValue* list_value = static_cast<base::ListValue*>(out_value);
return CefListValueImpl::GetOrCreateRef(
list_value,
const_cast<base::DictionaryValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
bool CefDictionaryValueImpl::SetNull(const CefString& key) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key, base::Value::CreateNullValue());
return true;
}
bool CefDictionaryValueImpl::SetBool(const CefString& key, bool value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateBooleanValue(value));
return true;
}
bool CefDictionaryValueImpl::SetInt(const CefString& key, int value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateIntegerValue(value));
return true;
}
bool CefDictionaryValueImpl::SetDouble(const CefString& key, double value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateDoubleValue(value));
return true;
}
bool CefDictionaryValueImpl::SetString(const CefString& key,
const CefString& value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
mutable_value()->SetWithoutPathExpansion(key,
base::Value::CreateStringValue(value.ToString16()));
return true;
}
bool CefDictionaryValueImpl::SetBinary(const CefString& key,
CefRefPtr<CefBinaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get());
DCHECK(impl);
mutable_value()->SetWithoutPathExpansion(key,
impl->CopyOrDetachValue(controller()));
return true;
}
bool CefDictionaryValueImpl::SetDictionary(
const CefString& key, CefRefPtr<CefDictionaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
CefDictionaryValueImpl* impl =
static_cast<CefDictionaryValueImpl*>(value.get());
DCHECK(impl);
mutable_value()->SetWithoutPathExpansion(key,
impl->CopyOrDetachValue(controller()));
return true;
}
bool CefDictionaryValueImpl::SetList(const CefString& key,
CefRefPtr<CefListValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
RemoveInternal(key);
CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get());
DCHECK(impl);
mutable_value()->SetWithoutPathExpansion(key,
impl->CopyOrDetachValue(controller()));
return true;
}
bool CefDictionaryValueImpl::RemoveInternal(const CefString& key) {
base::Value* out_value = NULL;
if (!mutable_value()->RemoveWithoutPathExpansion(key, &out_value))
return false;
// Remove the value.
controller()->Remove(out_value, true);
// Only list and dictionary types may have dependencies.
if (out_value->IsType(base::Value::TYPE_LIST) ||
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
controller()->RemoveDependencies(out_value);
}
delete out_value;
return true;
}
CefDictionaryValueImpl::CefDictionaryValueImpl(
base::DictionaryValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller)
: CefValueBase<CefDictionaryValue, base::DictionaryValue>(
value, parent_value, value_mode, read_only, controller) {
}
// CefListValueImpl implementation.
// static
CefRefPtr<CefListValue> CefListValue::Create() {
return new CefListValueImpl(new base::ListValue(),
NULL, CefListValueImpl::kOwnerWillDelete, false, NULL);
}
// static
CefRefPtr<CefListValue> CefListValueImpl::GetOrCreateRef(
base::ListValue* value,
void* parent_value,
bool read_only,
CefValueController* controller) {
CefValueController::Object* object = controller->Get(value);
if (object)
return static_cast<CefListValueImpl*>(object);
return new CefListValueImpl(value, parent_value,
CefListValueImpl::kReference, read_only, controller);
}
base::ListValue* CefListValueImpl::CopyValue() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return const_value().DeepCopy();
}
base::ListValue* CefListValueImpl::CopyOrDetachValue(
CefValueController* new_controller) {
base::ListValue* new_value;
if (!will_delete()) {
// Copy the value.
new_value = CopyValue();
} else {
// Take ownership of the value.
new_value = Detach(new_controller);
}
DCHECK(new_value);
return new_value;
}
bool CefListValueImpl::IsValid() {
return !detached();
}
bool CefListValueImpl::IsOwned() {
return !will_delete();
}
bool CefListValueImpl::IsReadOnly() {
return read_only();
}
CefRefPtr<CefListValue> CefListValueImpl::Copy() {
CEF_VALUE_VERIFY_RETURN(false, NULL);
return new CefListValueImpl(const_value().DeepCopy(), NULL,
CefListValueImpl::kOwnerWillDelete, false, NULL);
}
bool CefListValueImpl::SetSize(size_t size) {
CEF_VALUE_VERIFY_RETURN(true, false);
size_t current_size = const_value().GetSize();
if (size < current_size) {
// Clean up any values above the requested size.
for (size_t i = current_size-1; i >= size; --i)
RemoveInternal(i);
} else if (size > 0) {
// Expand the list size.
mutable_value()->Set(size-1, base::Value::CreateNullValue());
}
return true;
}
size_t CefListValueImpl::GetSize() {
CEF_VALUE_VERIFY_RETURN(false, 0);
return const_value().GetSize();
}
bool CefListValueImpl::Clear() {
CEF_VALUE_VERIFY_RETURN(true, false);
// Detach any dependent values.
controller()->RemoveDependencies(mutable_value());
mutable_value()->Clear();
return true;
}
bool CefListValueImpl::Remove(int index) {
CEF_VALUE_VERIFY_RETURN(true, false);
return RemoveInternal(index);
}
CefValueType CefListValueImpl::GetType(int index) {
CEF_VALUE_VERIFY_RETURN(false, VTYPE_INVALID);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value)) {
switch (out_value->GetType()) {
case base::Value::TYPE_NULL:
return VTYPE_NULL;
case base::Value::TYPE_BOOLEAN:
return VTYPE_BOOL;
case base::Value::TYPE_INTEGER:
return VTYPE_INT;
case base::Value::TYPE_DOUBLE:
return VTYPE_DOUBLE;
case base::Value::TYPE_STRING:
return VTYPE_STRING;
case base::Value::TYPE_BINARY:
return VTYPE_BINARY;
case base::Value::TYPE_DICTIONARY:
return VTYPE_DICTIONARY;
case base::Value::TYPE_LIST:
return VTYPE_LIST;
}
}
return VTYPE_INVALID;
}
bool CefListValueImpl::GetBool(int index) {
CEF_VALUE_VERIFY_RETURN(false, false);
base::Value* out_value = NULL;
bool ret_value = false;
if (const_value().Get(index, &out_value))
out_value->GetAsBoolean(&ret_value);
return ret_value;
}
int CefListValueImpl::GetInt(int index) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
int ret_value = 0;
if (const_value().Get(index, &out_value))
out_value->GetAsInteger(&ret_value);
return ret_value;
}
double CefListValueImpl::GetDouble(int index) {
CEF_VALUE_VERIFY_RETURN(false, 0);
base::Value* out_value = NULL;
double ret_value = 0;
if (const_value().Get(index, &out_value))
out_value->GetAsDouble(&ret_value);
return ret_value;
}
CefString CefListValueImpl::GetString(int index) {
CEF_VALUE_VERIFY_RETURN(false, CefString());
base::Value* out_value = NULL;
string16 ret_value;
if (const_value().Get(index, &out_value))
out_value->GetAsString(&ret_value);
return ret_value;
}
CefRefPtr<CefBinaryValue> CefListValueImpl::GetBinary(int index) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value) &&
out_value->IsType(base::Value::TYPE_BINARY)) {
base::BinaryValue* binary_value =
static_cast<base::BinaryValue*>(out_value);
return CefBinaryValueImpl::GetOrCreateRef(binary_value,
const_cast<base::ListValue*>(&const_value()), controller());
}
return NULL;
}
CefRefPtr<CefDictionaryValue> CefListValueImpl::GetDictionary(int index) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value) &&
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
base::DictionaryValue* dict_value =
static_cast<base::DictionaryValue*>(out_value);
return CefDictionaryValueImpl::GetOrCreateRef(
dict_value,
const_cast<base::ListValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
CefRefPtr<CefListValue> CefListValueImpl::GetList(int index) {
CEF_VALUE_VERIFY_RETURN(false, NULL);
base::Value* out_value = NULL;
if (const_value().Get(index, &out_value) &&
out_value->IsType(base::Value::TYPE_LIST)) {
base::ListValue* list_value = static_cast<base::ListValue*>(out_value);
return CefListValueImpl::GetOrCreateRef(
list_value,
const_cast<base::ListValue*>(&const_value()),
read_only(),
controller());
}
return NULL;
}
bool CefListValueImpl::SetNull(int index) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateNullValue();
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetBool(int index, bool value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateBooleanValue(value);
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetInt(int index, int value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateIntegerValue(value);
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetDouble(int index, double value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateDoubleValue(value);
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetString(int index, const CefString& value) {
CEF_VALUE_VERIFY_RETURN(true, false);
base::Value* new_value = base::Value::CreateStringValue(value.ToString16());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetBinary(int index, CefRefPtr<CefBinaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
CefBinaryValueImpl* impl = static_cast<CefBinaryValueImpl*>(value.get());
DCHECK(impl);
base::Value* new_value = impl->CopyOrDetachValue(controller());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetDictionary(int index,
CefRefPtr<CefDictionaryValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
CefDictionaryValueImpl* impl =
static_cast<CefDictionaryValueImpl*>(value.get());
DCHECK(impl);
base::Value* new_value = impl->CopyOrDetachValue(controller());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::SetList(int index, CefRefPtr<CefListValue> value) {
CEF_VALUE_VERIFY_RETURN(true, false);
CefListValueImpl* impl = static_cast<CefListValueImpl*>(value.get());
DCHECK(impl);
base::Value* new_value = impl->CopyOrDetachValue(controller());
if (RemoveInternal(index))
mutable_value()->Insert(index, new_value);
else
mutable_value()->Set(index, new_value);
return true;
}
bool CefListValueImpl::RemoveInternal(int index) {
base::Value* out_value = NULL;
if (!mutable_value()->Remove(index, &out_value))
return false;
// Remove the value.
controller()->Remove(out_value, true);
// Only list and dictionary types may have dependencies.
if (out_value->IsType(base::Value::TYPE_LIST) ||
out_value->IsType(base::Value::TYPE_DICTIONARY)) {
controller()->RemoveDependencies(out_value);
}
delete out_value;
return true;
}
CefListValueImpl::CefListValueImpl(
base::ListValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller)
: CefValueBase<CefListValue, base::ListValue>(
value, parent_value, value_mode, read_only, controller) {
}

194
libcef/common/values_impl.h Normal file
View File

@@ -0,0 +1,194 @@
// 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_COMMON_VALUES_IMPL_H_
#define CEF_LIBCEF_COMMON_VALUES_IMPL_H_
#pragma once
#include <vector>
#include "include/cef_values.h"
#include "libcef/common/value_base.h"
#include "base/values.h"
#include "base/threading/platform_thread.h"
// CefBinaryValue implementation
class CefBinaryValueImpl
: public CefValueBase<CefBinaryValue, base::BinaryValue> {
public:
// Get or create a reference value.
static CefRefPtr<CefBinaryValue> GetOrCreateRef(
base::BinaryValue* value,
void* parent_value,
CefValueController* controller);
// Return a copy of the value.
base::BinaryValue* CopyValue();
// If a reference return a copy of the value otherwise detach the value to the
// specified |new_controller|.
base::BinaryValue* CopyOrDetachValue(CefValueController* new_controller);
// CefBinaryValue methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsOwned() OVERRIDE;
virtual CefRefPtr<CefBinaryValue> Copy() OVERRIDE;
virtual size_t GetSize() OVERRIDE;
virtual size_t GetData(void* buffer,
size_t buffer_size,
size_t data_offset) OVERRIDE;
private:
// See the CefValueBase constructor for usage. Binary values are always
// read-only.
CefBinaryValueImpl(base::BinaryValue* value,
void* parent_value,
ValueMode value_mode,
CefValueController* controller);
// If |copy| is false this object will take ownership of the specified |data|
// buffer instead of copying it.
CefBinaryValueImpl(char* data,
size_t data_size,
bool copy);
// For the Create() method.
friend class CefBinaryValue;
DISALLOW_COPY_AND_ASSIGN(CefBinaryValueImpl);
};
// CefDictionaryValue implementation
class CefDictionaryValueImpl
: public CefValueBase<CefDictionaryValue, base::DictionaryValue> {
public:
// Get or create a reference value.
static CefRefPtr<CefDictionaryValue> GetOrCreateRef(
base::DictionaryValue* value,
void* parent_value,
bool read_only,
CefValueController* controller);
// Return a copy of the value.
base::DictionaryValue* CopyValue();
// If a reference return a copy of the value otherwise detach the value to the
// specified |new_controller|.
base::DictionaryValue* CopyOrDetachValue(CefValueController* new_controller);
// CefDictionaryValue methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsOwned() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefDictionaryValue> Copy(
bool exclude_empty_children) OVERRIDE;
virtual size_t GetSize() OVERRIDE;
virtual bool Clear() OVERRIDE;
virtual bool HasKey(const CefString& key) OVERRIDE;
virtual bool GetKeys(KeyList& keys) OVERRIDE;
virtual bool Remove(const CefString& key) OVERRIDE;
virtual CefValueType GetType(const CefString& key) OVERRIDE;
virtual bool GetBool(const CefString& key) OVERRIDE;
virtual int GetInt(const CefString& key) OVERRIDE;
virtual double GetDouble(const CefString& key) OVERRIDE;
virtual CefString GetString(const CefString& key) OVERRIDE;
virtual CefRefPtr<CefBinaryValue> GetBinary(const CefString& key) OVERRIDE;
virtual CefRefPtr<CefDictionaryValue> GetDictionary(
const CefString& key) OVERRIDE;
virtual CefRefPtr<CefListValue> GetList(const CefString& key) OVERRIDE;
virtual bool SetNull(const CefString& key) OVERRIDE;
virtual bool SetBool(const CefString& key, bool value) OVERRIDE;
virtual bool SetInt(const CefString& key, int value) OVERRIDE;
virtual bool SetDouble(const CefString& key, double value) OVERRIDE;
virtual bool SetString(const CefString& key,
const CefString& value) OVERRIDE;
virtual bool SetBinary(const CefString& key,
CefRefPtr<CefBinaryValue> value) OVERRIDE;
virtual bool SetDictionary(const CefString& key,
CefRefPtr<CefDictionaryValue> value) OVERRIDE;
virtual bool SetList(const CefString& key,
CefRefPtr<CefListValue> value) OVERRIDE;
private:
// See the CefValueBase constructor for usage.
CefDictionaryValueImpl(base::DictionaryValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller);
bool RemoveInternal(const CefString& key);
// For the Create() method.
friend class CefDictionaryValue;
DISALLOW_COPY_AND_ASSIGN(CefDictionaryValueImpl);
};
// CefListValue implementation
class CefListValueImpl
: public CefValueBase<CefListValue, base::ListValue> {
public:
// Get or create a reference value.
static CefRefPtr<CefListValue> GetOrCreateRef(
base::ListValue* value,
void* parent_value,
bool read_only,
CefValueController* controller);
// Return a copy of the value.
base::ListValue* CopyValue();
// If a reference return a copy of the value otherwise detach the value to the
// specified |new_controller|.
base::ListValue* CopyOrDetachValue(CefValueController* new_controller);
/// CefListValue methods.
virtual bool IsValid() OVERRIDE;
virtual bool IsOwned() OVERRIDE;
virtual bool IsReadOnly() OVERRIDE;
virtual CefRefPtr<CefListValue> Copy() OVERRIDE;
virtual bool SetSize(size_t size) OVERRIDE;
virtual size_t GetSize() OVERRIDE;
virtual bool Clear() OVERRIDE;
virtual bool Remove(int index) OVERRIDE;
virtual CefValueType GetType(int index) OVERRIDE;
virtual bool GetBool(int index) OVERRIDE;
virtual int GetInt(int index) OVERRIDE;
virtual double GetDouble(int index) OVERRIDE;
virtual CefString GetString(int index) OVERRIDE;
virtual CefRefPtr<CefBinaryValue> GetBinary(int index) OVERRIDE;
virtual CefRefPtr<CefDictionaryValue> GetDictionary(int index) OVERRIDE;
virtual CefRefPtr<CefListValue> GetList(int index) OVERRIDE;
virtual bool SetNull(int index) OVERRIDE;
virtual bool SetBool(int index, bool value) OVERRIDE;
virtual bool SetInt(int index, int value) OVERRIDE;
virtual bool SetDouble(int index, double value) OVERRIDE;
virtual bool SetString(int index, const CefString& value) OVERRIDE;
virtual bool SetBinary(int index, CefRefPtr<CefBinaryValue> value) OVERRIDE;
virtual bool SetDictionary(int index,
CefRefPtr<CefDictionaryValue> value) OVERRIDE;
virtual bool SetList(int index, CefRefPtr<CefListValue> value) OVERRIDE;
private:
// See the CefValueBase constructor for usage.
CefListValueImpl(base::ListValue* value,
void* parent_value,
ValueMode value_mode,
bool read_only,
CefValueController* controller);
bool RemoveInternal(int index);
// For the Create() method.
friend class CefListValue;
DISALLOW_COPY_AND_ASSIGN(CefListValueImpl);
};
#endif // CEF_LIBCEF_COMMON_VALUES_IMPL_H_

View File

@@ -0,0 +1,12 @@
// 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/plugin/content_plugin_client.h"
CefContentPluginClient::~CefContentPluginClient() {
}
void CefContentPluginClient::PluginProcessStarted(
const string16& plugin_name) {
}

View File

@@ -0,0 +1,18 @@
// 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_PLUGIN_CONTENT_PLUGIN_CLIENT_H_
#define CEF_LIBCEF_PLUGIN_CONTENT_PLUGIN_CLIENT_H_
#pragma once
#include "base/compiler_specific.h"
#include "content/public/plugin/content_plugin_client.h"
class CefContentPluginClient : public content::ContentPluginClient {
public:
virtual ~CefContentPluginClient();
virtual void PluginProcessStarted(const string16& plugin_name) OVERRIDE;
};
#endif // CEF_LIBCEF_PLUGIN_CONTENT_PLUGIN_CLIENT_H_

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) {
}

Some files were not shown because too many files have changed in this diff Show More