mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
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:
11
libcef/browser/application_mac.h
Normal file
11
libcef/browser/application_mac.h
Normal 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_
|
46
libcef/browser/application_mac.mm
Normal file
46
libcef/browser/application_mac.mm
Normal 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];
|
||||
}
|
300
libcef/browser/browser_context.cc
Normal file
300
libcef/browser/browser_context.cc
Normal 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;
|
||||
}
|
64
libcef/browser/browser_context.h
Normal file
64
libcef/browser/browser_context.h
Normal 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_
|
1240
libcef/browser/browser_host_impl.cc
Normal file
1240
libcef/browser/browser_host_impl.cc
Normal file
File diff suppressed because it is too large
Load Diff
356
libcef/browser/browser_host_impl.h
Normal file
356
libcef/browser/browser_host_impl.h
Normal 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_
|
113
libcef/browser/browser_host_impl_gtk.cc
Normal file
113
libcef/browser/browser_host_impl_gtk.cc
Normal 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;
|
||||
}
|
162
libcef/browser/browser_host_impl_mac.mm
Normal file
162
libcef/browser/browser_host_impl_mac.mm
Normal 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;
|
||||
}
|
256
libcef/browser/browser_host_impl_win.cc
Normal file
256
libcef/browser/browser_host_impl_win.cc
Normal 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;
|
||||
}
|
97
libcef/browser/browser_main.cc
Normal file
97
libcef/browser/browser_main.cc
Normal 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();
|
||||
}
|
61
libcef/browser/browser_main.h
Normal file
61
libcef/browser/browser_main.h
Normal 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_
|
16
libcef/browser/browser_main_gtk.cc
Normal file
16
libcef/browser/browser_main_gtk.cc
Normal 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() {
|
||||
}
|
13
libcef/browser/browser_main_mac.mm
Normal file
13
libcef/browser/browser_main_mac.mm
Normal 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() {
|
||||
}
|
35
libcef/browser/browser_main_win.cc
Normal file
35
libcef/browser/browser_main_win.cc
Normal 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() {
|
||||
}
|
54
libcef/browser/browser_message_filter.cc
Normal file
54
libcef/browser/browser_message_filter.cc
Normal 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_);
|
||||
}
|
40
libcef/browser/browser_message_filter.h
Normal file
40
libcef/browser/browser_message_filter.h
Normal 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_
|
46
libcef/browser/browser_message_loop.cc
Normal file
46
libcef/browser/browser_message_loop.cc
Normal 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();
|
||||
}
|
40
libcef/browser/browser_message_loop.h
Normal file
40
libcef/browser/browser_message_loop.h
Normal 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_
|
172
libcef/browser/browser_settings.cc
Normal file
172
libcef/browser/browser_settings.cc
Normal 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;
|
||||
}
|
||||
}
|
14
libcef/browser/browser_settings.h
Normal file
14
libcef/browser/browser_settings.h
Normal 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_
|
434
libcef/browser/content_browser_client.cc
Normal file
434
libcef/browser/content_browser_client.cc
Normal 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 ∅
|
||||
}
|
||||
|
||||
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
|
205
libcef/browser/content_browser_client.h
Normal file
205
libcef/browser/content_browser_client.h
Normal 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
399
libcef/browser/context.cc
Normal 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
109
libcef/browser/context.h
Normal 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_
|
266
libcef/browser/cookie_manager_impl.cc
Normal file
266
libcef/browser/cookie_manager_impl.cc
Normal 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();
|
||||
}
|
43
libcef/browser/cookie_manager_impl.h
Normal file
43
libcef/browser/cookie_manager_impl.h
Normal 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_
|
50
libcef/browser/devtools_delegate.cc
Normal file
50
libcef/browser/devtools_delegate.cc
Normal 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 "";
|
||||
}
|
44
libcef/browser/devtools_delegate.h
Normal file
44
libcef/browser/devtools_delegate.h
Normal 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_
|
141
libcef/browser/download_manager_delegate.cc
Normal file
141
libcef/browser/download_manager_delegate.cc
Normal 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);
|
||||
}
|
50
libcef/browser/download_manager_delegate.h
Normal file
50
libcef/browser/download_manager_delegate.h
Normal 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_
|
231
libcef/browser/frame_host_impl.cc
Normal file
231
libcef/browser/frame_host_impl.cc
Normal 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;
|
||||
}
|
83
libcef/browser/frame_host_impl.h
Normal file
83
libcef/browser/frame_host_impl.h
Normal 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_
|
20
libcef/browser/navigate_params.cc
Normal file
20
libcef/browser/navigate_params.cc
Normal 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() {
|
||||
}
|
84
libcef/browser/navigate_params.h
Normal file
84
libcef/browser/navigate_params.h
Normal 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_
|
254
libcef/browser/origin_whitelist_impl.cc
Normal file
254
libcef/browser/origin_whitelist_impl.cc
Normal 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);
|
||||
}
|
17
libcef/browser/origin_whitelist_impl.h
Normal file
17
libcef/browser/origin_whitelist_impl.h
Normal 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_
|
25
libcef/browser/resource_context.cc
Normal file
25
libcef/browser/resource_context.cc
Normal 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();
|
||||
}
|
31
libcef/browser/resource_context.h
Normal file
31
libcef/browser/resource_context.h
Normal 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_
|
480
libcef/browser/resource_request_job.cc
Normal file
480
libcef/browser/resource_request_job.cc
Normal 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);
|
||||
}
|
||||
}
|
78
libcef/browser/resource_request_job.h
Normal file
78
libcef/browser/resource_request_job.h
Normal 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_
|
16
libcef/browser/resources/cef_resources.grd
Normal file
16
libcef/browser/resources/cef_resources.grd
Normal 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>
|
54
libcef/browser/resources/devtools_discovery_page.html
Normal file
54
libcef/browser/resources/devtools_discovery_page.html
Normal 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>
|
447
libcef/browser/scheme_impl.cc
Normal file
447
libcef/browser/scheme_impl.cc
Normal 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);
|
||||
}
|
16
libcef/browser/scheme_impl.h
Normal file
16
libcef/browser/scheme_impl.h
Normal 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_
|
10
libcef/browser/sqlite_diagnostics_stub.cc
Normal file
10
libcef/browser/sqlite_diagnostics_stub.cc
Normal 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;
|
||||
}
|
309
libcef/browser/stream_impl.cc
Normal file
309
libcef/browser/stream_impl.cc
Normal 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;
|
||||
}
|
154
libcef/browser/stream_impl.h
Normal file
154
libcef/browser/stream_impl.h
Normal 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_
|
45
libcef/browser/thread_util.h
Normal file
45
libcef/browser/thread_util.h
Normal 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_
|
200
libcef/browser/url_network_delegate.cc
Normal file
200
libcef/browser/url_network_delegate.cc
Normal 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;
|
||||
}
|
57
libcef/browser/url_network_delegate.h
Normal file
57
libcef/browser/url_network_delegate.h
Normal 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_
|
325
libcef/browser/url_request_context_getter.cc
Normal file
325
libcef/browser/url_request_context_getter.cc
Normal 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_));
|
||||
}
|
62
libcef/browser/url_request_context_getter.h
Normal file
62
libcef/browser/url_request_context_getter.h
Normal 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_
|
177
libcef/browser/url_request_context_getter_proxy.cc
Normal file
177
libcef/browser/url_request_context_getter_proxy.cc
Normal 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();
|
||||
}
|
31
libcef/browser/url_request_context_getter_proxy.h
Normal file
31
libcef/browser/url_request_context_getter_proxy.h
Normal 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_
|
85
libcef/browser/url_request_interceptor.cc
Normal file
85
libcef/browser/url_request_interceptor.cc
Normal 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;
|
||||
}
|
29
libcef/browser/url_request_interceptor.h
Normal file
29
libcef/browser/url_request_interceptor.h
Normal 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_
|
446
libcef/browser/xml_reader_impl.cc
Normal file
446
libcef/browser/xml_reader_impl.cc
Normal 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);
|
||||
}
|
73
libcef/browser/xml_reader_impl.h
Normal file
73
libcef/browser/xml_reader_impl.h
Normal 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_
|
280
libcef/browser/zip_reader_impl.cc
Normal file
280
libcef/browser/zip_reader_impl.cc
Normal 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);
|
||||
}
|
55
libcef/browser/zip_reader_impl.h
Normal file
55
libcef/browser/zip_reader_impl.h
Normal 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_
|
Reference in New Issue
Block a user