2012-04-03 03:34:16 +02:00
|
|
|
// 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"
|
2012-09-11 00:19:19 +02:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "libcef/browser/browser_context.h"
|
2013-09-03 18:43:31 +02:00
|
|
|
#include "libcef/browser/browser_context_proxy.h"
|
2012-12-30 12:17:49 +01:00
|
|
|
#include "libcef/browser/browser_info.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#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"
|
2012-10-08 19:47:37 +02:00
|
|
|
#include "libcef/browser/chrome_scheme_handler.h"
|
2014-04-15 21:02:30 +02:00
|
|
|
#include "libcef/browser/context.h"
|
2014-09-27 01:48:19 +02:00
|
|
|
#include "libcef/browser/devtools_delegate.h"
|
2013-03-07 02:20:24 +01:00
|
|
|
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
2013-10-23 21:30:47 +02:00
|
|
|
#include "libcef/browser/printing/printing_message_filter.h"
|
2012-06-25 23:21:27 +02:00
|
|
|
#include "libcef/browser/resource_dispatcher_host_delegate.h"
|
2013-03-08 01:41:26 +01:00
|
|
|
#include "libcef/browser/speech_recognition_manager_delegate.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "libcef/browser/thread_util.h"
|
2012-09-28 22:14:02 +02:00
|
|
|
#include "libcef/browser/web_plugin_impl.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "libcef/common/cef_switches.h"
|
2012-09-27 19:07:31 +02:00
|
|
|
#include "libcef/common/command_line_impl.h"
|
2013-04-16 00:16:01 +02:00
|
|
|
#include "libcef/common/content_client.h"
|
2013-06-04 19:41:37 +02:00
|
|
|
#include "libcef/common/scheme_registration.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2013-11-21 23:43:36 +01:00
|
|
|
#include "base/base_switches.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "base/command_line.h"
|
2013-02-27 18:56:03 +01:00
|
|
|
#include "base/files/file_path.h"
|
2012-09-11 00:19:19 +02:00
|
|
|
#include "base/path_service.h"
|
2014-10-07 22:44:33 +02:00
|
|
|
#include "chrome/browser/spellchecker/spellcheck_message_filter.h"
|
2013-02-06 21:41:54 +01:00
|
|
|
#include "chrome/common/chrome_switches.h"
|
2012-09-28 22:14:02 +02:00
|
|
|
#include "content/browser/plugin_service_impl.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "content/public/browser/access_token_store.h"
|
2012-10-08 19:47:37 +02:00
|
|
|
#include "content/public/browser/browser_url_handler.h"
|
2013-06-04 19:41:37 +02:00
|
|
|
#include "content/public/browser/child_process_security_policy.h"
|
2012-09-28 22:14:02 +02:00
|
|
|
#include "content/public/browser/plugin_service_filter.h"
|
2012-09-28 00:52:15 +02:00
|
|
|
#include "content/public/browser/quota_permission_context.h"
|
2012-04-04 20:18:09 +02:00
|
|
|
#include "content/public/browser/render_process_host.h"
|
2012-06-25 23:21:27 +02:00
|
|
|
#include "content/public/browser/resource_dispatcher_host.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "content/public/common/content_switches.h"
|
2014-04-30 19:14:40 +02:00
|
|
|
#include "content/public/common/storage_quota_params.h"
|
2014-09-04 19:53:40 +02:00
|
|
|
#include "content/public/common/web_preferences.h"
|
2013-08-15 21:38:55 +02:00
|
|
|
#include "third_party/WebKit/public/web/WebWindowFeatures.h"
|
2012-10-22 22:56:38 +02:00
|
|
|
#include "ui/base/ui_base_switches.h"
|
2013-07-24 22:15:18 +02:00
|
|
|
#include "url/gurl.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2014-10-07 22:44:33 +02:00
|
|
|
#if defined(OS_MACOSX)
|
|
|
|
#include "chrome/browser/spellchecker/spellcheck_message_filter_mac.h"
|
|
|
|
#endif
|
|
|
|
|
2013-11-21 23:43:36 +01:00
|
|
|
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
|
|
|
#include "base/debug/leak_annotations.h"
|
2014-09-04 19:53:40 +02:00
|
|
|
#include "components/crash/app/breakpad_linux.h"
|
|
|
|
#include "components/crash/browser/crash_handler_host_linux.h"
|
2013-11-21 23:43:36 +01:00
|
|
|
#include "content/public/common/content_descriptors.h"
|
|
|
|
#endif
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// In-memory store for access tokens used by geolocation.
|
|
|
|
class CefAccessTokenStore : public content::AccessTokenStore {
|
|
|
|
public:
|
|
|
|
CefAccessTokenStore() {}
|
|
|
|
|
|
|
|
virtual void LoadAccessTokens(
|
|
|
|
const LoadAccessTokensCallbackType& callback) OVERRIDE {
|
2013-09-03 18:43:31 +02:00
|
|
|
callback.Run(access_token_set_,
|
2014-09-27 01:48:19 +02:00
|
|
|
CefContentBrowserClient::Get()->request_context().get());
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void SaveAccessToken(
|
2013-12-17 23:04:35 +01:00
|
|
|
const GURL& server_url, const base::string16& access_token) OVERRIDE {
|
2012-04-03 03:34:16 +02:00
|
|
|
access_token_set_[server_url] = access_token;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
AccessTokenSet access_token_set_;
|
2014-07-01 00:30:29 +02:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefAccessTokenStore);
|
2012-04-03 03:34:16 +02:00
|
|
|
};
|
|
|
|
|
2012-09-28 00:52:15 +02:00
|
|
|
class CefQuotaCallbackImpl : public CefQuotaCallback {
|
|
|
|
public:
|
|
|
|
explicit CefQuotaCallbackImpl(
|
|
|
|
const content::QuotaPermissionContext::PermissionCallback& callback)
|
|
|
|
: callback_(callback) {
|
|
|
|
}
|
2014-07-02 20:25:22 +02:00
|
|
|
|
2012-09-28 00:52:15 +02:00
|
|
|
~CefQuotaCallbackImpl() {
|
|
|
|
if (!callback_.is_null()) {
|
|
|
|
// The callback is still pending. Cancel it now.
|
|
|
|
if (CEF_CURRENTLY_ON_IOT()) {
|
|
|
|
CancelNow(callback_);
|
|
|
|
} else {
|
|
|
|
CEF_POST_TASK(CEF_IOT,
|
|
|
|
base::Bind(&CefQuotaCallbackImpl::CancelNow, callback_));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Continue(bool allow) OVERRIDE {
|
|
|
|
if (CEF_CURRENTLY_ON_IOT()) {
|
|
|
|
if (!callback_.is_null()) {
|
|
|
|
callback_.Run(allow ?
|
|
|
|
content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW :
|
|
|
|
content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
|
|
|
|
callback_.Reset();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
CEF_POST_TASK(CEF_IOT,
|
|
|
|
base::Bind(&CefQuotaCallbackImpl::Continue, this, allow));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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(&CefQuotaCallbackImpl::Cancel, this));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Disconnect() {
|
|
|
|
callback_.Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
static void CancelNow(
|
|
|
|
const content::QuotaPermissionContext::PermissionCallback& callback) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
callback.Run(
|
|
|
|
content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
|
|
|
|
}
|
|
|
|
|
|
|
|
content::QuotaPermissionContext::PermissionCallback callback_;
|
|
|
|
|
|
|
|
IMPLEMENT_REFCOUNTING(CefQuotaCallbackImpl);
|
2014-07-01 00:30:29 +02:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefQuotaCallbackImpl);
|
2012-09-28 00:52:15 +02:00
|
|
|
};
|
|
|
|
|
2013-04-04 19:50:35 +02:00
|
|
|
class CefAllowCertificateErrorCallbackImpl
|
|
|
|
: public CefAllowCertificateErrorCallback {
|
|
|
|
public:
|
2014-07-02 20:25:22 +02:00
|
|
|
typedef base::Callback<void(bool)> // NOLINT(readability/function)
|
|
|
|
CallbackType;
|
|
|
|
|
|
|
|
explicit CefAllowCertificateErrorCallbackImpl(const CallbackType& callback)
|
|
|
|
: callback_(callback) {
|
2013-04-04 19:50:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Continue(bool allow) OVERRIDE {
|
|
|
|
if (CEF_CURRENTLY_ON_UIT()) {
|
|
|
|
if (!callback_.is_null()) {
|
|
|
|
callback_.Run(allow);
|
|
|
|
callback_.Reset();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
CEF_POST_TASK(CEF_UIT,
|
|
|
|
base::Bind(&CefAllowCertificateErrorCallbackImpl::Continue,
|
|
|
|
this, allow));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Disconnect() {
|
|
|
|
callback_.Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2014-07-02 20:25:22 +02:00
|
|
|
CallbackType callback_;
|
2013-04-04 19:50:35 +02:00
|
|
|
|
|
|
|
IMPLEMENT_REFCOUNTING(CefAllowCertificateErrorCallbackImpl);
|
2014-07-01 00:30:29 +02:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefAllowCertificateErrorCallbackImpl);
|
2013-04-04 19:50:35 +02:00
|
|
|
};
|
|
|
|
|
2014-07-02 20:25:22 +02:00
|
|
|
class CefGeolocationCallbackImpl : public CefGeolocationCallback {
|
|
|
|
public:
|
|
|
|
typedef base::Callback<void(bool)> // NOLINT(readability/function)
|
|
|
|
CallbackType;
|
|
|
|
|
|
|
|
explicit CefGeolocationCallbackImpl(const CallbackType& callback)
|
|
|
|
: callback_(callback) {}
|
|
|
|
|
|
|
|
virtual void Continue(bool allow) OVERRIDE {
|
|
|
|
if (CEF_CURRENTLY_ON_UIT()) {
|
|
|
|
if (!callback_.is_null()) {
|
|
|
|
callback_.Run(allow);
|
|
|
|
callback_.Reset();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
CEF_POST_TASK(CEF_UIT,
|
|
|
|
base::Bind(&CefGeolocationCallbackImpl::Continue, this, allow));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Disconnect() {
|
|
|
|
callback_.Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
static void Run(const CallbackType& callback, bool allow) {
|
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
callback.Run(allow);
|
|
|
|
}
|
|
|
|
|
|
|
|
CallbackType callback_;
|
|
|
|
|
|
|
|
IMPLEMENT_REFCOUNTING(CefGeolocationCallbackImpl);
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefGeolocationCallbackImpl);
|
|
|
|
};
|
|
|
|
|
|
|
|
void CancelGeolocationPermission(base::WeakPtr<CefBrowserHostImpl> browser,
|
|
|
|
const GURL& requesting_frame,
|
|
|
|
int bridge_id) {
|
|
|
|
if (browser.get()) {
|
|
|
|
CefRefPtr<CefClient> client = browser->GetClient();
|
|
|
|
if (client.get()) {
|
|
|
|
CefRefPtr<CefGeolocationHandler> handler =
|
|
|
|
client->GetGeolocationHandler();
|
|
|
|
if (handler.get()) {
|
|
|
|
handler->OnCancelGeolocationPermission(browser.get(),
|
|
|
|
requesting_frame.spec(),
|
|
|
|
bridge_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-28 00:52:15 +02:00
|
|
|
class CefQuotaPermissionContext : public content::QuotaPermissionContext {
|
|
|
|
public:
|
|
|
|
CefQuotaPermissionContext() {
|
|
|
|
}
|
|
|
|
|
|
|
|
// The callback will be dispatched on the IO thread.
|
|
|
|
virtual void RequestQuotaPermission(
|
2014-04-30 19:14:40 +02:00
|
|
|
const content::StorageQuotaParams& params,
|
2012-09-28 00:52:15 +02:00
|
|
|
int render_process_id,
|
|
|
|
const PermissionCallback& callback) OVERRIDE {
|
2014-09-04 19:53:40 +02:00
|
|
|
if (params.storage_type != storage::kStorageTypePersistent) {
|
2012-09-28 00:52:15 +02:00
|
|
|
// To match Chrome behavior we only support requesting quota with this
|
|
|
|
// interface for Persistent storage type.
|
|
|
|
callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool handled = false;
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
2014-01-02 23:41:11 +01:00
|
|
|
CefBrowserHostImpl::GetBrowserForView(render_process_id,
|
2014-04-30 19:14:40 +02:00
|
|
|
params.render_view_id);
|
2012-09-28 00:52:15 +02:00
|
|
|
if (browser.get()) {
|
|
|
|
CefRefPtr<CefClient> client = browser->GetClient();
|
|
|
|
if (client.get()) {
|
|
|
|
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
|
|
|
if (handler.get()) {
|
|
|
|
CefRefPtr<CefQuotaCallbackImpl> callbackImpl(
|
|
|
|
new CefQuotaCallbackImpl(callback));
|
2014-04-30 19:14:40 +02:00
|
|
|
handled = handler->OnQuotaRequest(browser.get(),
|
|
|
|
params.origin_url.spec(),
|
|
|
|
params.requested_size,
|
|
|
|
callbackImpl.get());
|
2012-09-28 00:52:15 +02:00
|
|
|
if (!handled)
|
|
|
|
callbackImpl->Disconnect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!handled) {
|
|
|
|
// Disallow the request by default.
|
|
|
|
callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
virtual ~CefQuotaPermissionContext() {
|
|
|
|
}
|
2014-07-01 00:30:29 +02:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefQuotaPermissionContext);
|
2012-09-28 00:52:15 +02:00
|
|
|
};
|
|
|
|
|
2012-09-28 22:14:02 +02:00
|
|
|
class CefPluginServiceFilter : public content::PluginServiceFilter {
|
|
|
|
public:
|
|
|
|
CefPluginServiceFilter() {}
|
|
|
|
virtual ~CefPluginServiceFilter() {}
|
|
|
|
|
2013-02-23 01:43:28 +01:00
|
|
|
virtual bool IsPluginAvailable(int render_process_id,
|
2014-06-12 22:42:53 +02:00
|
|
|
int render_frame_id,
|
2013-02-23 01:43:28 +01:00
|
|
|
const void* context,
|
|
|
|
const GURL& url,
|
|
|
|
const GURL& policy_url,
|
2013-07-24 22:15:18 +02:00
|
|
|
content::WebPluginInfo* plugin) OVERRIDE {
|
2012-09-28 22:14:02 +02:00
|
|
|
bool allowed = true;
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
2014-06-12 22:42:53 +02:00
|
|
|
CefBrowserHostImpl::GetBrowserForFrame(render_process_id,
|
|
|
|
render_frame_id);
|
2012-09-28 22:14:02 +02:00
|
|
|
if (browser.get()) {
|
|
|
|
CefRefPtr<CefClient> client = browser->GetClient();
|
|
|
|
if (client.get()) {
|
|
|
|
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
|
|
|
if (handler.get()) {
|
|
|
|
CefRefPtr<CefWebPluginInfoImpl> pluginInfo(
|
|
|
|
new CefWebPluginInfoImpl(*plugin));
|
|
|
|
allowed =
|
|
|
|
!handler->OnBeforePluginLoad(browser.get(),
|
|
|
|
url.possibly_invalid_spec(),
|
|
|
|
policy_url.possibly_invalid_spec(),
|
|
|
|
pluginInfo.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return allowed;
|
|
|
|
}
|
2013-02-23 01:43:28 +01:00
|
|
|
|
|
|
|
virtual bool CanLoadPlugin(int render_process_id,
|
2013-02-27 18:56:03 +01:00
|
|
|
const base::FilePath& path) OVERRIDE {
|
2013-02-23 01:43:28 +01:00
|
|
|
return true;
|
|
|
|
}
|
2014-07-01 00:30:29 +02:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CefPluginServiceFilter);
|
2012-09-28 22:14:02 +02:00
|
|
|
};
|
|
|
|
|
2013-11-08 22:28:56 +01:00
|
|
|
void TranslatePopupFeatures(const blink::WebWindowFeatures& webKitFeatures,
|
2013-08-15 21:38:55 +02:00
|
|
|
CefPopupFeatures& features) {
|
|
|
|
features.x = static_cast<int>(webKitFeatures.x);
|
|
|
|
features.xSet = webKitFeatures.xSet;
|
|
|
|
features.y = static_cast<int>(webKitFeatures.y);
|
|
|
|
features.ySet = webKitFeatures.ySet;
|
|
|
|
features.width = static_cast<int>(webKitFeatures.width);
|
|
|
|
features.widthSet = webKitFeatures.widthSet;
|
|
|
|
features.height = static_cast<int>(webKitFeatures.height);
|
|
|
|
features.heightSet = webKitFeatures.heightSet;
|
|
|
|
|
|
|
|
features.menuBarVisible = webKitFeatures.menuBarVisible;
|
|
|
|
features.statusBarVisible = webKitFeatures.statusBarVisible;
|
|
|
|
features.toolBarVisible = webKitFeatures.toolBarVisible;
|
|
|
|
features.locationBarVisible = webKitFeatures.locationBarVisible;
|
|
|
|
features.scrollbarsVisible = webKitFeatures.scrollbarsVisible;
|
|
|
|
features.resizable = webKitFeatures.resizable;
|
|
|
|
|
|
|
|
features.fullscreen = webKitFeatures.fullscreen;
|
|
|
|
features.dialog = webKitFeatures.dialog;
|
|
|
|
features.additionalFeatures = NULL;
|
|
|
|
if (webKitFeatures.additionalFeatures.size() > 0)
|
|
|
|
features.additionalFeatures = cef_string_list_alloc();
|
|
|
|
|
|
|
|
CefString str;
|
|
|
|
for (unsigned int i = 0; i < webKitFeatures.additionalFeatures.size(); ++i) {
|
2013-12-17 23:04:35 +01:00
|
|
|
str = base::string16(webKitFeatures.additionalFeatures[i]);
|
2013-08-15 21:38:55 +02:00
|
|
|
cef_string_list_append(features.additionalFeatures, str.GetStruct());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-21 23:43:36 +01:00
|
|
|
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
|
|
|
breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
|
|
|
|
const std::string& process_type) {
|
|
|
|
base::FilePath dumps_path =
|
2014-10-07 22:44:33 +02:00
|
|
|
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
|
2013-11-21 23:43:36 +01:00
|
|
|
switches::kCrashDumpsDir);
|
|
|
|
{
|
|
|
|
ANNOTATE_SCOPED_MEMORY_LEAK;
|
|
|
|
breakpad::CrashHandlerHostLinux* crash_handler =
|
|
|
|
new breakpad::CrashHandlerHostLinux(
|
|
|
|
process_type, dumps_path, false);
|
|
|
|
crash_handler->StartUploaderThread();
|
|
|
|
return crash_handler;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-07 22:44:33 +02:00
|
|
|
int GetCrashSignalFD(const base::CommandLine& command_line) {
|
2013-11-21 23:43:36 +01:00
|
|
|
if (!breakpad::IsCrashReporterEnabled())
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
std::string process_type =
|
|
|
|
command_line.GetSwitchValueASCII(switches::kProcessType);
|
|
|
|
|
|
|
|
if (process_type == switches::kRendererProcess) {
|
|
|
|
static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
|
|
|
|
if (!crash_handler)
|
|
|
|
crash_handler = CreateCrashHandlerHost(process_type);
|
|
|
|
return crash_handler->GetDeathSignalSocket();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process_type == switches::kPluginProcess) {
|
|
|
|
static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
|
|
|
|
if (!crash_handler)
|
|
|
|
crash_handler = CreateCrashHandlerHost(process_type);
|
|
|
|
return crash_handler->GetDeathSignalSocket();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process_type == switches::kPpapiPluginProcess) {
|
|
|
|
static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
|
|
|
|
if (!crash_handler)
|
|
|
|
crash_handler = CreateCrashHandlerHost(process_type);
|
|
|
|
return crash_handler->GetDeathSignalSocket();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process_type == switches::kGpuProcess) {
|
|
|
|
static breakpad::CrashHandlerHostLinux* crash_handler = NULL;
|
|
|
|
if (!crash_handler)
|
|
|
|
crash_handler = CreateCrashHandlerHost(process_type);
|
|
|
|
return crash_handler->GetDeathSignalSocket();
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif // defined(OS_POSIX) && !defined(OS_MACOSX)
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
|
|
CefContentBrowserClient::CefContentBrowserClient()
|
2012-12-30 12:17:49 +01:00
|
|
|
: browser_main_parts_(NULL),
|
2014-04-25 03:36:58 +02:00
|
|
|
next_browser_id_(0) {
|
2012-09-28 22:14:02 +02:00
|
|
|
plugin_service_filter_.reset(new CefPluginServiceFilter);
|
2012-11-05 21:18:20 +01:00
|
|
|
content::PluginServiceImpl::GetInstance()->SetFilter(
|
|
|
|
plugin_service_filter_.get());
|
2013-02-08 01:07:41 +01:00
|
|
|
|
2013-02-09 23:38:24 +01:00
|
|
|
last_create_window_params_.opener_process_id = MSG_ROUTING_NONE;
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CefContentBrowserClient::~CefContentBrowserClient() {
|
|
|
|
}
|
|
|
|
|
2012-11-20 21:08:36 +01:00
|
|
|
// static
|
|
|
|
CefContentBrowserClient* CefContentBrowserClient::Get() {
|
|
|
|
return static_cast<CefContentBrowserClient*>(
|
2013-04-16 00:16:01 +02:00
|
|
|
CefContentClient::Get()->browser());
|
2012-11-20 21:08:36 +01:00
|
|
|
}
|
|
|
|
|
2013-11-08 17:06:06 +01:00
|
|
|
scoped_refptr<CefBrowserInfo> CefContentBrowserClient::CreateBrowserInfo(
|
|
|
|
bool is_popup) {
|
2012-12-30 12:17:49 +01:00
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
|
|
|
|
scoped_refptr<CefBrowserInfo> browser_info =
|
2013-11-08 17:06:06 +01:00
|
|
|
new CefBrowserInfo(++next_browser_id_, is_popup);
|
2012-12-30 12:17:49 +01:00
|
|
|
browser_info_list_.push_back(browser_info);
|
|
|
|
return browser_info;
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_refptr<CefBrowserInfo>
|
2014-01-02 23:41:11 +01:00
|
|
|
CefContentBrowserClient::GetOrCreateBrowserInfo(
|
|
|
|
int render_view_process_id,
|
|
|
|
int render_view_routing_id,
|
|
|
|
int render_frame_process_id,
|
|
|
|
int render_frame_routing_id) {
|
2012-12-30 12:17:49 +01:00
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
|
|
|
|
BrowserInfoList::const_iterator it = browser_info_list_.begin();
|
|
|
|
for (; it != browser_info_list_.end(); ++it) {
|
|
|
|
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
|
2014-01-02 23:41:11 +01:00
|
|
|
if (browser_info->is_render_view_id_match(render_view_process_id,
|
|
|
|
render_view_routing_id)) {
|
|
|
|
// Make sure the frame id is also registered.
|
|
|
|
browser_info->add_render_frame_id(render_frame_process_id,
|
|
|
|
render_frame_routing_id);
|
2012-12-30 12:17:49 +01:00
|
|
|
return browser_info;
|
2014-01-02 23:41:11 +01:00
|
|
|
} else if (browser_info->is_render_frame_id_match(
|
|
|
|
render_frame_process_id,
|
|
|
|
render_frame_routing_id)) {
|
|
|
|
// Make sure the view id is also registered.
|
|
|
|
browser_info->add_render_view_id(render_view_process_id,
|
|
|
|
render_view_routing_id);
|
|
|
|
return browser_info;
|
|
|
|
}
|
2012-12-30 12:17:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Must be a popup if it hasn't already been created.
|
|
|
|
scoped_refptr<CefBrowserInfo> browser_info =
|
|
|
|
new CefBrowserInfo(++next_browser_id_, true);
|
2014-01-02 23:41:11 +01:00
|
|
|
browser_info->add_render_view_id(render_view_process_id,
|
|
|
|
render_view_routing_id);
|
|
|
|
browser_info->add_render_frame_id(render_frame_process_id,
|
|
|
|
render_frame_routing_id);
|
2012-12-30 12:17:49 +01:00
|
|
|
browser_info_list_.push_back(browser_info);
|
|
|
|
return browser_info;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefContentBrowserClient::RemoveBrowserInfo(
|
|
|
|
scoped_refptr<CefBrowserInfo> browser_info) {
|
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
|
|
|
|
BrowserInfoList::iterator it = browser_info_list_.begin();
|
|
|
|
for (; it != browser_info_list_.end(); ++it) {
|
|
|
|
if (*it == browser_info) {
|
|
|
|
browser_info_list_.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NOTREACHED();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefContentBrowserClient::DestroyAllBrowsers() {
|
|
|
|
BrowserInfoList list;
|
|
|
|
|
|
|
|
{
|
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
list = browser_info_list_;
|
|
|
|
}
|
2012-11-20 21:08:36 +01:00
|
|
|
|
2012-12-30 12:17:49 +01:00
|
|
|
// Destroy any remaining browser windows.
|
|
|
|
if (!list.empty()) {
|
|
|
|
BrowserInfoList::iterator it = list.begin();
|
|
|
|
for (; it != list.end(); ++it) {
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser = (*it)->browser();
|
2013-01-04 13:36:39 +01:00
|
|
|
if (browser.get()) {
|
|
|
|
// DestroyBrowser will call RemoveBrowserInfo.
|
2012-12-30 12:17:49 +01:00
|
|
|
browser->DestroyBrowser();
|
2013-01-04 13:36:39 +01:00
|
|
|
} else {
|
|
|
|
// Canceled popup windows may have browser info but no browser because
|
|
|
|
// CefBrowserMessageFilter::OnGetNewBrowserInfo is still called.
|
|
|
|
DCHECK((*it)->is_popup());
|
|
|
|
RemoveBrowserInfo(*it);
|
|
|
|
}
|
2012-12-30 12:17:49 +01:00
|
|
|
}
|
2012-11-20 21:08:36 +01:00
|
|
|
}
|
|
|
|
|
2012-12-30 12:17:49 +01:00
|
|
|
#ifndef NDEBUG
|
|
|
|
{
|
|
|
|
// Verify that all browser windows have been destroyed.
|
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
DCHECK(browser_info_list_.empty());
|
|
|
|
}
|
|
|
|
#endif
|
2012-11-20 21:08:36 +01:00
|
|
|
}
|
|
|
|
|
2014-01-02 23:41:11 +01:00
|
|
|
scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForView(
|
|
|
|
int render_process_id, int render_routing_id) {
|
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
|
|
|
|
BrowserInfoList::const_iterator it = browser_info_list_.begin();
|
|
|
|
for (; it != browser_info_list_.end(); ++it) {
|
|
|
|
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
|
|
|
|
if (browser_info->is_render_view_id_match(
|
|
|
|
render_process_id, render_routing_id)) {
|
|
|
|
return browser_info;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LOG(WARNING) << "No browser info matching view process id " <<
|
|
|
|
render_process_id << " and routing id " << render_routing_id;
|
|
|
|
|
|
|
|
return scoped_refptr<CefBrowserInfo>();
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForFrame(
|
|
|
|
int render_process_id, int render_routing_id) {
|
2012-12-30 12:17:49 +01:00
|
|
|
base::AutoLock lock_scope(browser_info_lock_);
|
|
|
|
|
|
|
|
BrowserInfoList::const_iterator it = browser_info_list_.begin();
|
|
|
|
for (; it != browser_info_list_.end(); ++it) {
|
|
|
|
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
|
2014-01-02 23:41:11 +01:00
|
|
|
if (browser_info->is_render_frame_id_match(
|
|
|
|
render_process_id, render_routing_id)) {
|
2012-12-30 12:17:49 +01:00
|
|
|
return browser_info;
|
2014-01-02 23:41:11 +01:00
|
|
|
}
|
2012-12-30 12:17:49 +01:00
|
|
|
}
|
|
|
|
|
2014-01-02 23:41:11 +01:00
|
|
|
LOG(WARNING) << "No browser info matching frame process id " <<
|
|
|
|
render_process_id << " and routing id " << render_routing_id;
|
2012-11-20 21:08:36 +01:00
|
|
|
|
2012-12-30 12:17:49 +01:00
|
|
|
return scoped_refptr<CefBrowserInfo>();
|
2012-11-20 21:08:36 +01:00
|
|
|
}
|
|
|
|
|
2013-09-03 18:43:31 +02:00
|
|
|
CefBrowserContext* CefContentBrowserClient::CreateBrowserContextProxy(
|
|
|
|
CefRefPtr<CefRequestContextHandler> handler) {
|
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
CefBrowserContextProxy* context =
|
|
|
|
new CefBrowserContextProxy(handler, browser_context());
|
|
|
|
browser_main_parts_->AddBrowserContext(context);
|
|
|
|
context->AddRef();
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefContentBrowserClient::AddBrowserContextReference(
|
|
|
|
CefBrowserContext* context) {
|
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
// Skip the global browser context.
|
|
|
|
if (context == browser_context())
|
|
|
|
return;
|
|
|
|
|
|
|
|
CefBrowserContextProxy* proxy = static_cast<CefBrowserContextProxy*>(context);
|
|
|
|
proxy->AddRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefContentBrowserClient::RemoveBrowserContextReference(
|
|
|
|
CefBrowserContext* context) {
|
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
// Skip the global browser context.
|
|
|
|
if (context == browser_context())
|
|
|
|
return;
|
|
|
|
|
|
|
|
CefBrowserContextProxy* proxy = static_cast<CefBrowserContextProxy*>(context);
|
|
|
|
if (proxy->Release())
|
|
|
|
browser_main_parts_->RemoveBrowserContext(proxy);
|
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts(
|
|
|
|
const content::MainFunctionParams& parameters) {
|
2012-04-11 20:00:55 +02:00
|
|
|
browser_main_parts_ = new CefBrowserMainParts(parameters);
|
|
|
|
return browser_main_parts_;
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2014-01-02 23:41:11 +01:00
|
|
|
void CefContentBrowserClient::RenderProcessWillLaunch(
|
2012-04-03 03:34:16 +02:00
|
|
|
content::RenderProcessHost* host) {
|
2014-10-07 22:44:33 +02:00
|
|
|
const base::CommandLine* command_line =
|
|
|
|
base::CommandLine::ForCurrentProcess();
|
|
|
|
const int id = host->GetID();
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host));
|
2014-10-07 22:44:33 +02:00
|
|
|
host->AddFilter(new printing::PrintingMessageFilter(id));
|
|
|
|
|
|
|
|
if (!command_line->HasSwitch(switches::kDisableSpellChecking)) {
|
|
|
|
host->AddFilter(new SpellCheckMessageFilter(id));
|
|
|
|
#if defined(OS_MACOSX)
|
|
|
|
host->AddFilter(new SpellCheckMessageFilterMac(id));
|
|
|
|
#endif
|
|
|
|
}
|
2013-10-23 21:30:47 +02:00
|
|
|
|
2013-09-03 18:43:31 +02:00
|
|
|
AddBrowserContextReference(
|
|
|
|
static_cast<CefBrowserContext*>(host->GetBrowserContext()));
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2013-02-23 01:43:28 +01:00
|
|
|
net::URLRequestContextGetter* CefContentBrowserClient::CreateRequestContext(
|
|
|
|
content::BrowserContext* content_browser_context,
|
2014-04-04 18:50:38 +02:00
|
|
|
content::ProtocolHandlerMap* protocol_handlers,
|
2014-06-12 22:28:58 +02:00
|
|
|
content::URLRequestInterceptorScopedVector request_interceptors) {
|
2013-02-23 01:43:28 +01:00
|
|
|
CefBrowserContext* cef_browser_context =
|
2013-09-03 18:43:31 +02:00
|
|
|
static_cast<CefBrowserContext*>(content_browser_context);
|
2014-04-04 18:50:38 +02:00
|
|
|
return cef_browser_context->CreateRequestContext(
|
|
|
|
protocol_handlers,
|
2014-06-12 22:28:58 +02:00
|
|
|
request_interceptors.Pass());
|
2013-02-23 01:43:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
net::URLRequestContextGetter*
|
|
|
|
CefContentBrowserClient::CreateRequestContextForStoragePartition(
|
|
|
|
content::BrowserContext* content_browser_context,
|
|
|
|
const base::FilePath& partition_path,
|
|
|
|
bool in_memory,
|
2014-04-04 18:50:38 +02:00
|
|
|
content::ProtocolHandlerMap* protocol_handlers,
|
2014-06-12 22:28:58 +02:00
|
|
|
content::URLRequestInterceptorScopedVector request_interceptors) {
|
2013-02-23 01:43:28 +01:00
|
|
|
CefBrowserContext* cef_browser_context =
|
2013-09-03 18:43:31 +02:00
|
|
|
static_cast<CefBrowserContext*>(content_browser_context);
|
2013-02-23 01:43:28 +01:00
|
|
|
return cef_browser_context->CreateRequestContextForStoragePartition(
|
2014-04-04 18:50:38 +02:00
|
|
|
partition_path,
|
|
|
|
in_memory,
|
|
|
|
protocol_handlers,
|
2014-06-12 22:28:58 +02:00
|
|
|
request_interceptors.Pass());
|
2013-02-23 01:43:28 +01:00
|
|
|
}
|
|
|
|
|
2013-06-04 19:41:37 +02:00
|
|
|
bool CefContentBrowserClient::IsHandledURL(const GURL& url) {
|
|
|
|
if (!url.is_valid())
|
|
|
|
return false;
|
|
|
|
const std::string& scheme = url.scheme();
|
2014-09-04 19:53:40 +02:00
|
|
|
DCHECK_EQ(scheme, base::StringToLowerASCII(scheme));
|
2013-06-04 19:41:37 +02:00
|
|
|
|
|
|
|
if (scheme::IsInternalHandledScheme(scheme))
|
|
|
|
return true;
|
|
|
|
|
2013-06-05 01:37:26 +02:00
|
|
|
return CefContentClient::Get()->HasCustomScheme(scheme);
|
2013-06-04 19:41:37 +02:00
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
void CefContentBrowserClient::AppendExtraCommandLineSwitches(
|
2014-10-07 22:44:33 +02:00
|
|
|
base::CommandLine* command_line, int child_process_id) {
|
|
|
|
const base::CommandLine& browser_cmd =
|
|
|
|
*base::CommandLine::ForCurrentProcess();
|
2012-09-10 18:13:51 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
// Propagate the following switches to all command lines (along with any
|
|
|
|
// associated values) if present in the browser command line.
|
|
|
|
static const char* const kSwitchNames[] = {
|
2014-01-10 20:49:43 +01:00
|
|
|
#if !defined(OS_WIN)
|
|
|
|
switches::kCrashDumpsDir,
|
|
|
|
#endif
|
|
|
|
switches::kDisablePackLoading,
|
|
|
|
switches::kEnableCrashReporter,
|
2012-10-25 23:19:20 +02:00
|
|
|
switches::kLang,
|
|
|
|
switches::kLocalesDirPath,
|
2012-09-10 18:13:51 +02:00
|
|
|
switches::kLogFile,
|
|
|
|
switches::kLogSeverity,
|
2012-10-25 23:19:20 +02:00
|
|
|
switches::kResourcesDirPath,
|
2014-01-10 20:49:43 +01:00
|
|
|
switches::kProductVersion,
|
2012-09-10 18:13:51 +02:00
|
|
|
};
|
|
|
|
command_line->CopySwitchesFrom(browser_cmd, kSwitchNames,
|
|
|
|
arraysize(kSwitchNames));
|
|
|
|
}
|
|
|
|
|
2013-06-10 20:48:09 +02:00
|
|
|
const std::string& process_type =
|
2012-04-03 03:34:16 +02:00
|
|
|
command_line->GetSwitchValueASCII(switches::kProcessType);
|
|
|
|
if (process_type == switches::kRendererProcess) {
|
2012-09-10 18:13:51 +02:00
|
|
|
// 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[] = {
|
2012-10-29 22:46:02 +01:00
|
|
|
switches::kContextSafetyImplementation,
|
2014-10-07 22:44:33 +02:00
|
|
|
switches::kDisableSpellChecking,
|
2013-03-08 01:52:57 +01:00
|
|
|
switches::kEnableMediaStream,
|
2013-03-08 01:41:26 +01:00
|
|
|
switches::kEnableSpeechInput,
|
2014-10-07 22:44:33 +02:00
|
|
|
switches::kEnableSpellingAutoCorrect,
|
2012-11-02 19:16:28 +01:00
|
|
|
switches::kUncaughtExceptionStackSize,
|
2012-09-10 18:13:51 +02:00
|
|
|
};
|
|
|
|
command_line->CopySwitchesFrom(browser_cmd, kSwitchNames,
|
|
|
|
arraysize(kSwitchNames));
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
2012-09-27 19:07:31 +02:00
|
|
|
|
2013-06-10 20:48:09 +02:00
|
|
|
#if defined(OS_LINUX)
|
|
|
|
if (process_type == switches::kZygoteProcess &&
|
2013-06-24 21:40:07 +02:00
|
|
|
browser_cmd.HasSwitch(switches::kBrowserSubprocessPath)) {
|
2013-06-10 20:48:09 +02:00
|
|
|
// Force use of the sub-process executable path for the zygote process.
|
|
|
|
const base::FilePath& subprocess_path =
|
2013-06-24 21:40:07 +02:00
|
|
|
browser_cmd.GetSwitchValuePath(switches::kBrowserSubprocessPath);
|
2013-06-10 20:48:09 +02:00
|
|
|
if (!subprocess_path.empty())
|
|
|
|
command_line->SetProgram(subprocess_path);
|
|
|
|
}
|
|
|
|
#endif // defined(OS_LINUX)
|
|
|
|
|
2013-09-03 18:43:31 +02:00
|
|
|
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
|
2012-09-27 19:07:31 +02:00
|
|
|
if (app.get()) {
|
|
|
|
CefRefPtr<CefBrowserProcessHandler> handler =
|
|
|
|
app->GetBrowserProcessHandler();
|
|
|
|
if (handler.get()) {
|
|
|
|
CefRefPtr<CefCommandLineImpl> commandLinePtr(
|
|
|
|
new CefCommandLineImpl(command_line, false, false));
|
|
|
|
handler->OnBeforeChildProcessLaunch(commandLinePtr.get());
|
|
|
|
commandLinePtr->Detach(NULL);
|
|
|
|
}
|
|
|
|
}
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2012-09-28 00:52:15 +02:00
|
|
|
content::QuotaPermissionContext*
|
|
|
|
CefContentBrowserClient::CreateQuotaPermissionContext() {
|
|
|
|
return new CefQuotaPermissionContext();
|
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
content::MediaObserver* CefContentBrowserClient::GetMediaObserver() {
|
2013-03-07 02:20:24 +01:00
|
|
|
return CefMediaCaptureDevicesDispatcher::GetInstance();
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2013-03-08 01:41:26 +01:00
|
|
|
content::SpeechRecognitionManagerDelegate*
|
|
|
|
CefContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
|
2014-10-07 22:44:33 +02:00
|
|
|
const base::CommandLine* command_line =
|
|
|
|
base::CommandLine::ForCurrentProcess();
|
|
|
|
if (command_line->HasSwitch(switches::kEnableSpeechInput))
|
2013-03-08 01:41:26 +01:00
|
|
|
return new CefSpeechRecognitionManagerDelegate();
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-04-04 19:50:35 +02:00
|
|
|
void CefContentBrowserClient::AllowCertificateError(
|
|
|
|
int render_process_id,
|
2014-05-12 17:56:24 +02:00
|
|
|
int render_frame_id,
|
2013-04-04 19:50:35 +02:00
|
|
|
int cert_error,
|
|
|
|
const net::SSLInfo& ssl_info,
|
|
|
|
const GURL& request_url,
|
2014-09-04 19:53:40 +02:00
|
|
|
content::ResourceType resource_type,
|
2013-04-04 19:50:35 +02:00
|
|
|
bool overridable,
|
|
|
|
bool strict_enforcement,
|
2014-09-04 19:53:40 +02:00
|
|
|
bool expired_previous_decision,
|
2013-04-04 19:50:35 +02:00
|
|
|
const base::Callback<void(bool)>& callback,
|
2013-06-04 19:41:37 +02:00
|
|
|
content::CertificateRequestResultType* result) {
|
2013-04-04 19:50:35 +02:00
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
|
2014-09-04 19:53:40 +02:00
|
|
|
if (resource_type != content::ResourceType::RESOURCE_TYPE_MAIN_FRAME) {
|
2013-04-04 19:50:35 +02:00
|
|
|
// A sub-resource has a certificate error. The user doesn't really
|
|
|
|
// have a context for making the right decision, so block the request
|
|
|
|
// hard.
|
2013-06-04 19:41:37 +02:00
|
|
|
*result = content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
|
2013-04-04 19:50:35 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
2014-05-12 17:56:24 +02:00
|
|
|
CefBrowserHostImpl::GetBrowserForFrame(render_process_id,
|
|
|
|
render_frame_id);
|
2013-04-04 19:50:35 +02:00
|
|
|
if (!browser.get())
|
|
|
|
return;
|
|
|
|
CefRefPtr<CefClient> client = browser->GetClient();
|
|
|
|
if (!client.get())
|
|
|
|
return;
|
|
|
|
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
|
|
|
if (!handler.get())
|
|
|
|
return;
|
|
|
|
|
|
|
|
CefRefPtr<CefAllowCertificateErrorCallbackImpl> callbackImpl;
|
|
|
|
if (overridable && !strict_enforcement)
|
|
|
|
callbackImpl = new CefAllowCertificateErrorCallbackImpl(callback);
|
|
|
|
|
2013-06-04 19:41:37 +02:00
|
|
|
bool proceed = handler->OnCertificateError(
|
2013-04-04 19:50:35 +02:00
|
|
|
static_cast<cef_errorcode_t>(cert_error), request_url.spec(),
|
|
|
|
callbackImpl.get());
|
2013-06-04 19:41:37 +02:00
|
|
|
if (!proceed && callbackImpl.get())
|
2013-04-04 19:50:35 +02:00
|
|
|
callbackImpl->Disconnect();
|
2013-06-04 19:41:37 +02:00
|
|
|
|
|
|
|
*result = proceed ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE :
|
|
|
|
content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
|
2013-04-04 19:50:35 +02:00
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
content::AccessTokenStore* CefContentBrowserClient::CreateAccessTokenStore() {
|
|
|
|
return new CefAccessTokenStore;
|
|
|
|
}
|
|
|
|
|
2014-07-02 20:25:22 +02:00
|
|
|
void CefContentBrowserClient::RequestGeolocationPermission(
|
|
|
|
content::WebContents* web_contents,
|
|
|
|
int bridge_id,
|
|
|
|
const GURL& requesting_frame,
|
|
|
|
bool user_gesture,
|
|
|
|
base::Callback<void(bool)> result_callback,
|
|
|
|
base::Closure* cancel_callback) {
|
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
bool proceed = false;
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
|
|
|
CefBrowserHostImpl::GetBrowserForContents(web_contents);
|
|
|
|
if (browser.get()) {
|
|
|
|
CefRefPtr<CefClient> client = browser->GetClient();
|
|
|
|
if (client.get()) {
|
|
|
|
CefRefPtr<CefGeolocationHandler> handler =
|
|
|
|
client->GetGeolocationHandler();
|
|
|
|
if (handler.get()) {
|
|
|
|
CefRefPtr<CefGeolocationCallbackImpl> callbackImpl(
|
|
|
|
new CefGeolocationCallbackImpl(result_callback));
|
|
|
|
|
|
|
|
// Notify the handler.
|
|
|
|
proceed = handler->OnRequestGeolocationPermission(
|
|
|
|
browser.get(), requesting_frame.spec(), bridge_id,
|
|
|
|
callbackImpl.get());
|
|
|
|
if (proceed) {
|
|
|
|
// The callback reference may outlive the browser so use a WeakPtr.
|
|
|
|
*cancel_callback =
|
|
|
|
base::Bind(CancelGeolocationPermission,
|
|
|
|
browser->GetWeakPtr(), requesting_frame,
|
|
|
|
bridge_id);
|
|
|
|
} else {
|
|
|
|
callbackImpl->Disconnect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!proceed) {
|
|
|
|
// Disallow geolocation access by default.
|
|
|
|
result_callback.Run(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-08 01:07:41 +01:00
|
|
|
bool CefContentBrowserClient::CanCreateWindow(
|
|
|
|
const GURL& opener_url,
|
2013-10-16 02:25:38 +02:00
|
|
|
const GURL& opener_top_level_frame_url,
|
2013-08-15 21:38:55 +02:00
|
|
|
const GURL& source_origin,
|
2013-02-08 01:07:41 +01:00
|
|
|
WindowContainerType container_type,
|
2013-08-15 21:38:55 +02:00
|
|
|
const GURL& target_url,
|
|
|
|
const content::Referrer& referrer,
|
|
|
|
WindowOpenDisposition disposition,
|
2013-11-08 22:28:56 +01:00
|
|
|
const blink::WebWindowFeatures& features,
|
2013-08-15 21:38:55 +02:00
|
|
|
bool user_gesture,
|
|
|
|
bool opener_suppressed,
|
2013-02-08 01:07:41 +01:00
|
|
|
content::ResourceContext* context,
|
|
|
|
int render_process_id,
|
2013-08-15 21:38:55 +02:00
|
|
|
int opener_id,
|
2013-02-08 01:07:41 +01:00
|
|
|
bool* no_javascript_access) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
*no_javascript_access = false;
|
|
|
|
|
2013-02-09 23:38:24 +01:00
|
|
|
DCHECK_NE(last_create_window_params_.opener_process_id, MSG_ROUTING_NONE);
|
|
|
|
if (last_create_window_params_.opener_process_id == MSG_ROUTING_NONE)
|
2013-02-08 01:07:41 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
2014-01-02 23:41:11 +01:00
|
|
|
CefBrowserHostImpl::GetBrowserForView(
|
2013-02-09 23:38:24 +01:00
|
|
|
last_create_window_params_.opener_process_id,
|
|
|
|
last_create_window_params_.opener_view_id);
|
2013-02-08 01:07:41 +01:00
|
|
|
DCHECK(browser.get());
|
2013-02-09 23:38:24 +01:00
|
|
|
if (!browser.get()) {
|
|
|
|
LOG(WARNING) << "CanCreateWindow called before browser was created";
|
2013-02-08 01:07:41 +01:00
|
|
|
return false;
|
2013-02-09 23:38:24 +01:00
|
|
|
}
|
2013-02-08 01:07:41 +01:00
|
|
|
|
2013-02-09 23:38:24 +01:00
|
|
|
CefRefPtr<CefClient> client = browser->GetClient();
|
2013-02-08 01:07:41 +01:00
|
|
|
bool allow = true;
|
|
|
|
|
2013-02-09 23:38:24 +01:00
|
|
|
scoped_ptr<CefBrowserHostImpl::PendingPopupInfo> pending_info;
|
|
|
|
pending_info.reset(new CefBrowserHostImpl::PendingPopupInfo);
|
|
|
|
|
|
|
|
#if defined(OS_WIN)
|
|
|
|
pending_info->window_info.SetAsPopup(NULL, CefString());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Start with the current browser's settings.
|
|
|
|
pending_info->client = client;
|
|
|
|
pending_info->settings = browser->settings();
|
|
|
|
|
2013-02-08 01:07:41 +01:00
|
|
|
if (client.get()) {
|
|
|
|
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
|
|
|
|
if (handler.get()) {
|
|
|
|
CefRefPtr<CefFrame> frame =
|
|
|
|
browser->GetFrame(last_create_window_params_.opener_frame_id);
|
2013-02-09 23:38:24 +01:00
|
|
|
|
2013-08-15 21:38:55 +02:00
|
|
|
CefPopupFeatures cef_features;
|
|
|
|
TranslatePopupFeatures(features, cef_features);
|
2013-02-09 23:38:24 +01:00
|
|
|
|
|
|
|
#if (defined(OS_WIN) || defined(OS_MACOSX))
|
|
|
|
// Default to the size from the popup features.
|
2013-08-15 21:38:55 +02:00
|
|
|
if (cef_features.xSet)
|
|
|
|
pending_info->window_info.x = cef_features.x;
|
|
|
|
if (cef_features.ySet)
|
|
|
|
pending_info->window_info.y = cef_features.y;
|
|
|
|
if (cef_features.widthSet)
|
|
|
|
pending_info->window_info.width = cef_features.width;
|
|
|
|
if (cef_features.heightSet)
|
|
|
|
pending_info->window_info.height = cef_features.height;
|
2013-02-09 23:38:24 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
allow = !handler->OnBeforePopup(browser.get(),
|
2013-02-08 01:07:41 +01:00
|
|
|
frame,
|
|
|
|
last_create_window_params_.target_url.spec(),
|
|
|
|
last_create_window_params_.target_frame_name,
|
2013-08-15 21:38:55 +02:00
|
|
|
cef_features,
|
2013-02-09 23:38:24 +01:00
|
|
|
pending_info->window_info,
|
|
|
|
pending_info->client,
|
|
|
|
pending_info->settings,
|
2013-02-08 01:07:41 +01:00
|
|
|
no_javascript_access);
|
2013-02-09 23:38:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (allow) {
|
|
|
|
CefRefPtr<CefClient> pending_client = pending_info->client;
|
|
|
|
allow = browser->SetPendingPopupInfo(pending_info.Pass());
|
|
|
|
if (!allow) {
|
|
|
|
LOG(WARNING) << "Creation of popup window denied because one is already "
|
|
|
|
"pending.";
|
2013-02-08 01:07:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-09 23:38:24 +01:00
|
|
|
last_create_window_params_.opener_process_id = MSG_ROUTING_NONE;
|
2013-02-08 01:07:41 +01:00
|
|
|
|
|
|
|
return allow;
|
|
|
|
}
|
|
|
|
|
2012-06-25 23:21:27 +02:00
|
|
|
void CefContentBrowserClient::ResourceDispatcherHostCreated() {
|
|
|
|
resource_dispatcher_host_delegate_.reset(
|
|
|
|
new CefResourceDispatcherHostDelegate());
|
|
|
|
content::ResourceDispatcherHost::Get()->SetDelegate(
|
|
|
|
resource_dispatcher_host_delegate_.get());
|
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
void CefContentBrowserClient::OverrideWebkitPrefs(
|
|
|
|
content::RenderViewHost* rvh,
|
|
|
|
const GURL& url,
|
2014-09-04 19:53:40 +02:00
|
|
|
content::WebPreferences* prefs) {
|
2014-10-07 22:44:33 +02:00
|
|
|
const base::CommandLine* command_line =
|
|
|
|
base::CommandLine::ForCurrentProcess();
|
|
|
|
|
2012-05-18 17:04:56 +02:00
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
|
|
|
CefBrowserHostImpl::GetBrowserForHost(rvh);
|
2012-04-03 03:34:16 +02:00
|
|
|
DCHECK(browser.get());
|
|
|
|
|
|
|
|
// Populate WebPreferences based on CefBrowserSettings.
|
|
|
|
BrowserToWebSettings(browser->settings(), *prefs);
|
2014-04-15 21:02:30 +02:00
|
|
|
|
|
|
|
prefs->base_background_color = GetBaseBackgroundColor(rvh);
|
2014-10-07 22:44:33 +02:00
|
|
|
|
|
|
|
prefs->asynchronous_spell_checking_enabled = true;
|
|
|
|
// Auto-correct does not work in combination with the unified text checker.
|
|
|
|
prefs->unified_textchecker_enabled =
|
|
|
|
!command_line->HasSwitch(switches::kEnableSpellingAutoCorrect);
|
2014-04-15 21:02:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
SkColor CefContentBrowserClient::GetBaseBackgroundColor(
|
|
|
|
content::RenderViewHost* rvh) {
|
|
|
|
CefRefPtr<CefBrowserHostImpl> browser =
|
|
|
|
CefBrowserHostImpl::GetBrowserForHost(rvh);
|
|
|
|
DCHECK(browser.get());
|
|
|
|
|
|
|
|
const CefBrowserSettings& browser_settings = browser->settings();
|
|
|
|
if (CefColorGetA(browser_settings.background_color) > 0) {
|
|
|
|
return SkColorSetRGB(
|
|
|
|
CefColorGetR(browser_settings.background_color),
|
|
|
|
CefColorGetG(browser_settings.background_color),
|
|
|
|
CefColorGetB(browser_settings.background_color));
|
|
|
|
} else {
|
|
|
|
const CefSettings& settings = CefContext::Get()->settings();
|
|
|
|
if (CefColorGetA(settings.background_color) > 0) {
|
|
|
|
return SkColorSetRGB(
|
|
|
|
CefColorGetR(settings.background_color),
|
|
|
|
CefColorGetG(settings.background_color),
|
|
|
|
CefColorGetB(settings.background_color));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SK_ColorWHITE;
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2012-10-08 19:47:37 +02:00
|
|
|
void CefContentBrowserClient::BrowserURLHandlerCreated(
|
|
|
|
content::BrowserURLHandler* handler) {
|
|
|
|
// Used to redirect about: URLs to chrome: URLs.
|
|
|
|
handler->AddHandlerPair(&scheme::WillHandleBrowserAboutURL,
|
|
|
|
content::BrowserURLHandler::null_handler());
|
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
std::string CefContentBrowserClient::GetDefaultDownloadName() {
|
|
|
|
return "download";
|
|
|
|
}
|
2012-09-11 00:19:19 +02:00
|
|
|
|
2014-09-27 01:48:19 +02:00
|
|
|
content::DevToolsManagerDelegate*
|
|
|
|
CefContentBrowserClient::GetDevToolsManagerDelegate() {
|
|
|
|
return new CefDevToolsManagerDelegate(browser_context());
|
|
|
|
}
|
2013-11-21 23:43:36 +01:00
|
|
|
|
|
|
|
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
|
|
|
void CefContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
|
2014-04-04 18:50:38 +02:00
|
|
|
const base::CommandLine& command_line,
|
2013-11-21 23:43:36 +01:00
|
|
|
int child_process_id,
|
|
|
|
std::vector<content::FileDescriptorInfo>* mappings) {
|
|
|
|
int crash_signal_fd = GetCrashSignalFD(command_line);
|
|
|
|
if (crash_signal_fd >= 0) {
|
|
|
|
mappings->push_back(content::FileDescriptorInfo(
|
|
|
|
kCrashDumpSignal, base::FileDescriptor(crash_signal_fd, false)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // defined(OS_POSIX) && !defined(OS_MACOSX)
|
|
|
|
|
|
|
|
|
2012-09-11 00:19:19 +02:00
|
|
|
#if defined(OS_WIN)
|
|
|
|
const wchar_t* CefContentBrowserClient::GetResourceDllName() {
|
|
|
|
static wchar_t file_path[MAX_PATH+1] = {0};
|
|
|
|
|
|
|
|
if (file_path[0] == 0) {
|
|
|
|
// Retrieve the module path (usually libcef.dll).
|
2013-02-23 01:43:28 +01:00
|
|
|
base::FilePath module;
|
2012-09-11 00:19:19 +02:00
|
|
|
PathService::Get(base::FILE_MODULE, &module);
|
|
|
|
const std::wstring wstr = module.value();
|
|
|
|
size_t count = std::min(static_cast<size_t>(MAX_PATH), wstr.size());
|
|
|
|
wcsncpy(file_path, wstr.c_str(), count);
|
|
|
|
file_path[count] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return file_path;
|
|
|
|
}
|
|
|
|
#endif // defined(OS_WIN)
|
2013-02-08 01:07:41 +01:00
|
|
|
|
2013-06-05 01:37:26 +02:00
|
|
|
void CefContentBrowserClient::RegisterCustomScheme(const std::string& scheme) {
|
2013-06-04 19:41:37 +02:00
|
|
|
// Register as a Web-safe scheme so that requests for the scheme from a
|
|
|
|
// render process will be allowed in resource_dispatcher_host_impl.cc
|
|
|
|
// ShouldServiceRequest.
|
|
|
|
content::ChildProcessSecurityPolicy* policy =
|
|
|
|
content::ChildProcessSecurityPolicy::GetInstance();
|
|
|
|
if (!policy->IsWebSafeScheme(scheme))
|
|
|
|
policy->RegisterWebSafeScheme(scheme);
|
|
|
|
}
|
|
|
|
|
2013-02-08 01:07:41 +01:00
|
|
|
void CefContentBrowserClient::set_last_create_window_params(
|
|
|
|
const LastCreateWindowParams& params) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
last_create_window_params_ = params;
|
|
|
|
}
|
2013-02-23 01:43:28 +01:00
|
|
|
|
2013-09-03 18:43:31 +02:00
|
|
|
CefBrowserContext* CefContentBrowserClient::browser_context() const {
|
2013-02-23 01:43:28 +01:00
|
|
|
return browser_main_parts_->browser_context();
|
|
|
|
}
|
2013-09-03 18:43:31 +02:00
|
|
|
|
|
|
|
scoped_refptr<net::URLRequestContextGetter>
|
|
|
|
CefContentBrowserClient::request_context() const {
|
|
|
|
return browser_main_parts_->request_context();
|
|
|
|
}
|
|
|
|
|
|
|
|
CefDevToolsDelegate* CefContentBrowserClient::devtools_delegate() const {
|
|
|
|
return browser_main_parts_->devtools_delegate();
|
|
|
|
}
|
|
|
|
|
|
|
|
PrefService* CefContentBrowserClient::pref_service() const {
|
|
|
|
return browser_main_parts_->pref_service();
|
|
|
|
}
|
|
|
|
|
|
|
|
scoped_ptr<net::ProxyConfigService>
|
|
|
|
CefContentBrowserClient::proxy_config_service() const {
|
|
|
|
return browser_main_parts_->proxy_config_service();
|
|
|
|
}
|