Update to Chromium revision 304f01a1 (#358063)

- Improve ordering of CefLoadHandler callbacks. OnLoadingStateChange will
  be called before and after all calls to OnLoadStart and OnLoadEnd.
  OnLoadStart/OnLoadEnd calls will occur as matching pairs
  (see http://crbug.com/539952#c2).
- Remove the |requesting_url| argument to CefGeolocationHandler::
  OnCancelGeolocationPermission. Clients can use the |request_id| argument
  to track this information themselves.
- Fix a crash when loading the PDF extension in multiple browsers with a
  custom CefRequestContext (issue #1757).
This commit is contained in:
Marshall Greenblatt
2015-11-10 15:18:16 -05:00
parent e0974ea64d
commit c6111d5947
92 changed files with 1918 additions and 902 deletions

View File

@@ -9,7 +9,7 @@
#include "libcef/browser/browser_context_proxy.h"
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/permission_manager.h"
#include "libcef/browser/permissions/permission_manager.h"
#include "libcef/browser/prefs/browser_prefs.h"
#include "libcef/browser/ssl_host_state_delegate.h"
#include "libcef/browser/thread_util.h"
@@ -326,10 +326,15 @@ content::SSLHostStateDelegate*
content::PermissionManager* CefBrowserContextImpl::GetPermissionManager() {
if (!permission_manager_.get())
permission_manager_.reset(new CefPermissionManager());
permission_manager_.reset(new CefPermissionManager(this));
return permission_manager_.get();
}
content::BackgroundSyncController*
CefBrowserContextImpl::GetBackgroundSyncController() {
return nullptr;
}
PrefService* CefBrowserContextImpl::GetPrefs() {
return pref_service_.get();
}

View File

@@ -68,6 +68,7 @@ class CefBrowserContextImpl : public CefBrowserContext {
content::PushMessagingService* GetPushMessagingService() override;
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
content::PermissionManager* GetPermissionManager() override;
content::BackgroundSyncController* GetBackgroundSyncController() override;
// Profile methods.
PrefService* GetPrefs() override;

View File

@@ -25,6 +25,7 @@ bool ShouldProxyUserData(const void* key) {
// If this value is not proxied then CefBrowserContextImpl::GetGuestManager()
// returns NULL.
// See also CefExtensionsAPIClient::CreateGuestViewManagerDelegate.
if (key == guest_view::kGuestViewManagerKeyName)
return true;
@@ -151,6 +152,11 @@ content::PermissionManager* CefBrowserContextProxy::GetPermissionManager() {
return parent_->GetPermissionManager();
}
content::BackgroundSyncController*
CefBrowserContextProxy::GetBackgroundSyncController() {
return parent_->GetBackgroundSyncController();
}
PrefService* CefBrowserContextProxy::GetPrefs() {
return parent_->GetPrefs();
}

View File

@@ -50,6 +50,7 @@ class CefBrowserContextProxy : public CefBrowserContext {
content::PushMessagingService* GetPushMessagingService() override;
content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
content::PermissionManager* GetPermissionManager() override;
content::BackgroundSyncController* GetBackgroundSyncController() override;
// Profile methods.
PrefService* GetPrefs() override;

View File

@@ -382,8 +382,10 @@ CefRenderWidgetHostViewOSR* GetOSRHostView(content::WebContents* web_contents) {
return fs_view;
content::RenderViewHost* host = web_contents->GetRenderViewHost();
if (host)
return static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
if (host) {
return static_cast<CefRenderWidgetHostViewOSR*>(
host->GetWidget()->GetView());
}
return NULL;
}
@@ -570,7 +572,8 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForHost(
DCHECK(host);
CEF_REQUIRE_UIT();
content::WebContents* web_contents =
content::WebContents::FromRenderViewHost(host);
content::WebContents::FromRenderViewHost(
const_cast<content::RenderViewHost*>(host));
if (web_contents)
return GetBrowserForContents(web_contents);
return NULL;
@@ -1089,7 +1092,7 @@ void CefBrowserHostImpl::WasResized() {
if (!IsWindowless()) {
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->WasResized();
host->GetWidget()->WasResized();
} else {
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
@@ -1177,7 +1180,7 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
if (!IsWindowless()) {
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->ForwardKeyboardEvent(web_event);
host->GetWidget()->ForwardKeyboardEvent(web_event);
} else {
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
@@ -1233,7 +1236,7 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
if (!IsWindowless()) {
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->ForwardWheelEvent(web_event);
host->GetWidget()->ForwardWheelEvent(web_event);
} else {
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
@@ -1278,7 +1281,7 @@ void CefBrowserHostImpl::SendMouseEvent(const blink::WebMouseEvent& event) {
if (!IsWindowless()) {
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->ForwardMouseEvent(event);
host->GetWidget()->ForwardMouseEvent(event);
} else {
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
@@ -1316,7 +1319,8 @@ void CefBrowserHostImpl::SendCaptureLostEvent() {
return;
content::RenderWidgetHostImpl* widget =
content::RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost());
content::RenderWidgetHostImpl::From(
web_contents()->GetRenderViewHost()->GetWidget());
if (widget)
widget->LostCapture();
}
@@ -2443,6 +2447,7 @@ bool CefBrowserHostImpl::ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
int32_t main_frame_widget_route_id,
WindowContainerType window_container_type,
const std::string& frame_name,
const GURL& target_url,
@@ -2609,7 +2614,7 @@ void CefBrowserHostImpl::RequestMediaAccessPermission(
(request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
if (microphone_requested || webcam_requested) {
switch (request.request_type) {
case content::MEDIA_OPEN_DEVICE:
case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
case content::MEDIA_DEVICE_ACCESS:
case content::MEDIA_GENERATE_STREAM:
case content::MEDIA_ENUMERATE_DEVICES:
@@ -2679,8 +2684,8 @@ void CefBrowserHostImpl::RenderViewCreated(
// Indicate that the view has an external parent (namely us). This changes the
// default view behavior in some cases (e.g. focus handling on Linux).
if (render_view_host->GetView())
render_view_host->GetView()->SetHasExternalParent(true);
if (render_view_host->GetWidget()->GetView())
render_view_host->GetWidget()->GetView()->SetHasExternalParent(true);
}
void CefBrowserHostImpl::RenderViewDeleted(
@@ -3088,8 +3093,26 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
{
base::AutoLock lock_scope(state_lock_);
if (is_main_frame)
if (is_main_frame && main_frame_id_ != frame_id) {
if (main_frame_id_ != CefFrameHostImpl::kInvalidFrameId) {
// Remove the old main frame object before adding the new one.
FrameMap::iterator it = frames_.find(main_frame_id_);
if (it != frames_.end()) {
// Persist URL and name to the new main frame.
if (url.empty())
url = it->second->GetURL();
if (name.empty())
name = it->second->GetName();
it->second->Detach();
frames_.erase(it);
}
if (focused_frame_id_ == main_frame_id_)
focused_frame_id_ = frame_id;
}
main_frame_id_ = frame_id;
}
// Check if a frame object already exists.
FrameMap::const_iterator it = frames_.find(frame_id);

View File

@@ -398,6 +398,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
int32_t main_frame_widget_route_id,
WindowContainerType window_container_type,
const std::string& frame_name,
const GURL& target_url,

View File

@@ -455,7 +455,7 @@ void CefBrowserHostImpl::PlatformNotifyMoveOrResizeStarted() {
// Send updated screen rectangle information to the renderer process so that
// popups are displayed in the correct location.
content::RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost())->
SendScreenRects();
content::RenderWidgetHostImpl::From(
web_contents()->GetRenderViewHost()->GetWidget())->SendScreenRects();
}

View File

@@ -817,7 +817,8 @@ bool CefBrowserHostImpl::PlatformCreateWindow() {
gfx::Point point = gfx::Point(cr.right, cr.bottom);
float scale = gfx::Screen::GetNativeScreen()->
GetDisplayNearestPoint(point).device_scale_factor();
point = gfx::ToFlooredPoint(gfx::ScalePoint(point, 1.0f / scale));
point = gfx::ToFlooredPoint(
gfx::ScalePoint(gfx::PointF(point), 1.0f / scale));
CefWindowDelegateView* delegate_view =
new CefWindowDelegateView(background_color);

View File

@@ -25,7 +25,8 @@ void ChromeBrowserProcessStub::EndSession() {
NOTIMPLEMENTED();
};
MetricsServicesManager* ChromeBrowserProcessStub::GetMetricsServicesManager() {
metrics_services_manager::MetricsServicesManager*
ChromeBrowserProcessStub::GetMetricsServicesManager() {
NOTIMPLEMENTED();
return NULL;
}

View File

@@ -31,7 +31,8 @@ class ChromeBrowserProcessStub : public BrowserProcess {
// BrowserProcess implementation.
void ResourceDispatcherHostCreated() override;
void EndSession() override;
MetricsServicesManager* GetMetricsServicesManager() override;
metrics_services_manager::MetricsServicesManager*
GetMetricsServicesManager() override;
metrics::MetricsService* metrics_service() override;
rappor::RapporService* rappor_service() override;
IOThread* io_thread() override;

View File

@@ -126,8 +126,6 @@ class CefConfigurator : public Configurator {
bool UseBackgroundDownloader() const override;
scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
const override;
scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner()
const override;
private:
friend class base::RefCountedThreadSafe<CefConfigurator>;
@@ -289,12 +287,6 @@ CefConfigurator::GetSequencedTaskRunner() const {
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
}
scoped_refptr<base::SingleThreadTaskRunner>
CefConfigurator::GetSingleThreadTaskRunner() const {
return content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE);
}
} // namespace
scoped_refptr<update_client::Configurator>

View File

@@ -55,6 +55,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/common/content_switches.h"
@@ -1068,8 +1069,10 @@ void CefContentBrowserClient::OverrideWebkitPrefs(
content::WebPreferences* prefs) {
renderer_prefs::PopulateWebPreferences(rvh, *prefs);
if (rvh->GetView())
rvh->GetView()->SetBackgroundColor(prefs->base_background_color);
if (rvh->GetWidget()->GetView()) {
rvh->GetWidget()->GetView()->SetBackgroundColor(
prefs->base_background_color);
}
}
void CefContentBrowserClient::BrowserURLHandlerCreated(

View File

@@ -37,7 +37,7 @@
#include "ui/base/ui_base_switches.h"
#if defined(OS_WIN)
#include "content/public/app/startup_helper_win.h"
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#endif
@@ -195,7 +195,7 @@ void CefQuitMessageLoop() {
return;
}
CefBrowserMessageLoop::current()->Quit();
CefBrowserMessageLoop::current()->QuitWhenIdle();
}
void CefSetOSModalLoop(bool osModalLoop) {

View File

@@ -556,6 +556,7 @@ void CefCookieManagerImpl::SetCookieInternal(
cookie.secure ? true : false,
cookie.httponly ? true : false,
false, // First-party only.
false, // Enforces prefixes.
net::COOKIE_PRIORITY_DEFAULT,
base::Bind(SetCookieCallbackImpl, callback));
}

View File

@@ -21,6 +21,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "ipc/ipc_channel.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -179,9 +180,11 @@ CefDevToolsFrontend::~CefDevToolsFrontend() {
void CefDevToolsFrontend::RenderViewCreated(
content::RenderViewHost* render_view_host) {
if (!frontend_host_) {
frontend_host_.reset(
content::DevToolsFrontendHost::Create(
web_contents()->GetMainFrame(), this));
frontend_host_.reset(content::DevToolsFrontendHost::Create(
web_contents()->GetMainFrame(),
base::Bind(&CefDevToolsFrontend::HandleMessageFromDevToolsFrontend,
base::Unretained(this))));
}
}
@@ -220,10 +223,12 @@ void CefDevToolsFrontend::HandleMessageFromDevToolsFrontend(
dict->GetInteger("id", &request_id);
dict->GetList("params", &params);
std::string browser_message;
if (method == "sendMessageToBrowser" && params &&
params->GetSize() == 1 && params->GetString(0, &browser_message)) {
agent_host_->DispatchProtocolMessage(browser_message);
if (method == "dispatchProtocolMessage" && params && params->GetSize() == 1) {
std::string protocol_message;
if (!params->GetString(0, &protocol_message))
return;
if (agent_host_)
agent_host_->DispatchProtocolMessage(protocol_message);
} else if (method == "loadCompleted") {
web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);"));
@@ -283,12 +288,6 @@ void CefDevToolsFrontend::HandleMessageFromDevToolsFrontend(
SendMessageAck(request_id, nullptr);
}
void CefDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend(
const std::string& message) {
if (agent_host_)
agent_host_->DispatchProtocolMessage(message);
}
void CefDevToolsFrontend::DispatchProtocolMessage(
content::DevToolsAgentHost* agent_host,
const std::string& message) {

View File

@@ -28,7 +28,6 @@ class WebContents;
}
class CefDevToolsFrontend : public content::WebContentsObserver,
public content::DevToolsFrontendHost::Delegate,
public content::DevToolsAgentHostClient,
public net::URLFetcherDelegate {
public:
@@ -72,10 +71,7 @@ class CefDevToolsFrontend : public content::WebContentsObserver,
void DocumentAvailableInMainFrame() override;
void WebContentsDestroyed() override;
// content::DevToolsFrontendHost::Delegate implementation.
void HandleMessageFromDevToolsFrontend(const std::string& message) override;
void HandleMessageFromDevToolsFrontendToBackend(
const std::string& message) override;
void HandleMessageFromDevToolsFrontend(const std::string& message);
// net::URLFetcherDelegate overrides.
void OnURLFetchComplete(const net::URLFetcher* source) override;

View File

@@ -261,6 +261,13 @@ scoped_ptr<ExtensionSet> CefExtensionSystem::GetDependentExtensions(
return make_scoped_ptr(new ExtensionSet());
}
void CefExtensionSystem::InstallUpdate(const std::string& extension_id,
const base::FilePath& temp_dir) {
NOTREACHED();
base::DeleteFile(temp_dir, true /* recursive */);
}
CefExtensionSystem::ComponentExtensionInfo::ComponentExtensionInfo(
const base::DictionaryValue* manifest, const base::FilePath& directory)
: manifest(manifest),

View File

@@ -73,6 +73,8 @@ class CefExtensionSystem : public ExtensionSystem {
ContentVerifier* content_verifier() override;
scoped_ptr<ExtensionSet> GetDependentExtensions(
const Extension* extension) override;
void InstallUpdate(const std::string& extension_id,
const base::FilePath& temp_dir) override;
private:
// Information about a registered component extension.

View File

@@ -6,6 +6,7 @@
#include "libcef/browser/extensions/extensions_api_client.h"
#include "include/internal/cef_types_wrappers.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/extensions/extension_web_contents_observer.h"
#include "libcef/browser/extensions/mime_handler_view_guest_delegate.h"
#include "libcef/browser/extensions/pdf_web_contents_helper_client.h"
@@ -13,6 +14,7 @@
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "components/pdf/browser/pdf_web_contents_helper.h"
#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h"
namespace extensions {
@@ -26,6 +28,22 @@ AppViewGuestDelegate* CefExtensionsAPIClient::CreateAppViewGuestDelegate()
return NULL;
}
scoped_ptr<guest_view::GuestViewManagerDelegate>
CefExtensionsAPIClient::CreateGuestViewManagerDelegate(
content::BrowserContext* context) const {
// The GuestViewManager instance associated with the returned Delegate, which
// will be retrieved in the future via GuestViewManager::FromBrowserContext,
// will be associated with the CefBrowserContextImpl instead of |context| due
// to ShouldProxyUserData in browser_context_proxy.cc. Because the
// GuestViewManagerDelegate keeps a reference to the passed-in context we need
// to provide the *Impl object instead of |context| which may be a *Proxy
// object. If we don't do this then the Delegate may attempt to access a
// *Proxy object that has already been deleted.
return make_scoped_ptr(
new extensions::ExtensionsGuestViewManagerDelegate(
CefBrowserContextImpl::GetForContext(context).get()));
}
scoped_ptr<MimeHandlerViewGuestDelegate>
CefExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate(
MimeHandlerViewGuest* guest) const {

View File

@@ -16,6 +16,9 @@ class CefExtensionsAPIClient : public ExtensionsAPIClient {
// ExtensionsAPIClient implementation.
AppViewGuestDelegate* CreateAppViewGuestDelegate() const override;
scoped_ptr<guest_view::GuestViewManagerDelegate>
CreateGuestViewManagerDelegate(
content::BrowserContext* context) const override;
scoped_ptr<MimeHandlerViewGuestDelegate>
CreateMimeHandlerViewGuestDelegate(
MimeHandlerViewGuest* guest) const override;

View File

@@ -20,7 +20,7 @@ namespace {
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowser(
extensions::MimeHandlerViewGuest* guest) {
content::WebContents* owner_web_contents = guest->GetOwnerWebContents();
content::WebContents* owner_web_contents = guest->owner_web_contents();
CefRefPtr<CefBrowserHostImpl> owner_browser =
CefBrowserHostImpl::GetBrowserForContents(owner_web_contents);
DCHECK(owner_browser);

View File

@@ -56,6 +56,7 @@
textField_ = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 22)];
[[textField_ cell] setLineBreakMode:NSLineBreakByTruncatingTail];
[alert_ setAccessoryView:textField_];
[[alert_ window] setInitialFirstResponder:textField_];
[textField_ release];
return textField_;

View File

@@ -52,7 +52,8 @@ bool CefMenuCreatorRunnerWin::RunContextMenu(CefMenuCreator* manager) {
// Adjust for potential display scaling.
float scale = gfx::Screen::GetScreenFor(window)->
GetDisplayNearestWindow(window).device_scale_factor();
screen_point = gfx::ToFlooredPoint(gfx::ScalePoint(screen_point, scale));
screen_point = gfx::ToFlooredPoint(
gfx::ScalePoint(gfx::PointF(screen_point), scale));
}
// Show the menu. Blocks until the menu is dismissed.

View File

@@ -1,191 +0,0 @@
// Copyright 2015 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/permission_manager.h"
#include "include/cef_client.h"
#include "include/cef_geolocation_handler.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/callback.h"
#include "content/public/browser/geolocation_provider.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
namespace {
class CefGeolocationCallbackImpl : public CefGeolocationCallback {
public:
typedef base::Callback<void(content::PermissionStatus)> CallbackType;
explicit CefGeolocationCallbackImpl(const CallbackType& callback)
: callback_(callback) {}
void Continue(bool allow) override {
if (CEF_CURRENTLY_ON_UIT()) {
if (!callback_.is_null()) {
if (allow) {
content::GeolocationProvider::GetInstance()->
UserDidOptIntoLocationServices();
}
callback_.Run(allow ? content::PERMISSION_STATUS_GRANTED :
content::PERMISSION_STATUS_DENIED);
callback_.Reset();
}
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefGeolocationCallbackImpl::Continue, this, allow));
}
}
void Disconnect() {
callback_.Reset();
}
private:
CallbackType callback_;
IMPLEMENT_REFCOUNTING(CefGeolocationCallbackImpl);
DISALLOW_COPY_AND_ASSIGN(CefGeolocationCallbackImpl);
};
} // namespace
struct CefPermissionManager::PendingRequest {
PendingRequest(content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin)
: permission(permission),
render_process_id(render_frame_host->GetProcess()->GetID()),
render_frame_id(render_frame_host->GetRoutingID()),
requesting_origin(requesting_origin) {
}
content::PermissionType permission;
int render_process_id;
int render_frame_id;
GURL requesting_origin;
};
CefPermissionManager::CefPermissionManager()
: PermissionManager() {
}
CefPermissionManager::~CefPermissionManager() {
}
int CefPermissionManager::RequestPermission(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(content::PermissionStatus)>& callback) {
CEF_REQUIRE_UIT();
if (permission != content::PermissionType::GEOLOCATION) {
callback.Run(content::PERMISSION_STATUS_DENIED);
return kNoPendingOperation;
}
bool proceed = false;
PendingRequest* pending_request = new PendingRequest(
permission, render_frame_host, requesting_origin);
const int request_id = pending_requests_.Add(pending_request);
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForHost(render_frame_host);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefGeolocationHandler> handler =
client->GetGeolocationHandler();
if (handler.get()) {
CefRefPtr<CefGeolocationCallbackImpl> callbackImpl(
new CefGeolocationCallbackImpl(callback));
// Notify the handler.
proceed = handler->OnRequestGeolocationPermission(
browser.get(), requesting_origin.spec(), request_id,
callbackImpl.get());
if (!proceed)
callbackImpl->Disconnect();
}
}
}
if (proceed)
return request_id;
pending_requests_.Remove(request_id);
// Disallow geolocation access by default.
callback.Run(content::PERMISSION_STATUS_DENIED);
return kNoPendingOperation;
}
void CefPermissionManager::CancelPermissionRequest(
int request_id) {
CEF_REQUIRE_UIT();
PendingRequest* pending_request = pending_requests_.Lookup(request_id);
if (!pending_request)
return;
if (pending_request->permission != content::PermissionType::GEOLOCATION)
return;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForFrame(pending_request->render_process_id,
pending_request->render_frame_id);
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefGeolocationHandler> handler =
client->GetGeolocationHandler();
if (handler.get()) {
handler->OnCancelGeolocationPermission(
browser.get(),
pending_request->requesting_origin.spec(),
request_id);
}
}
}
pending_requests_.Remove(request_id);
}
void CefPermissionManager::ResetPermission(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
}
content::PermissionStatus CefPermissionManager::GetPermissionStatus(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
return content::PERMISSION_STATUS_DENIED;
}
void CefPermissionManager::RegisterPermissionUsage(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
}
int CefPermissionManager::SubscribePermissionStatusChange(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin,
const base::Callback<void(content::PermissionStatus)>& callback) {
return -1;
}
void CefPermissionManager::UnsubscribePermissionStatusChange(
int subscription_id) {
}

View File

@@ -1,51 +0,0 @@
// Copyright 2015 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_PERMISSION_MANAGER_H_
#define CEF_LIBCEF_BROWSER_PERMISSION_MANAGER_H_
#include "base/callback_forward.h"
#include "base/id_map.h"
#include "base/macros.h"
#include "content/public/browser/permission_manager.h"
class CefPermissionManager : public content::PermissionManager {
public:
CefPermissionManager();
~CefPermissionManager() override;
// PermissionManager implementation.
int RequestPermission(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(content::PermissionStatus)>& callback) override;
void CancelPermissionRequest(int request_id) override;
void ResetPermission(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
content::PermissionStatus GetPermissionStatus(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
void RegisterPermissionUsage(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
int SubscribePermissionStatusChange(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin,
const base::Callback<void(content::PermissionStatus)>& callback) override;
void UnsubscribePermissionStatusChange(int subscription_id) override;
private:
struct PendingRequest;
using PendingRequestsMap = IDMap<PendingRequest, IDMapOwnPointer>;
PendingRequestsMap pending_requests_;
DISALLOW_COPY_AND_ASSIGN(CefPermissionManager);
};
#endif // CEF_LIBCEF_BROWSER_PERMISSION_MANAGER_H_

View File

@@ -0,0 +1,268 @@
// Copyright 2015 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/permissions/permission_context.h"
#include "include/cef_client.h"
#include "include/cef_geolocation_handler.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/permissions/permission_util.h"
#include "libcef/browser/thread_util.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/geolocation_provider.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/origin_util.h"
namespace {
// Whether the permission should be restricted to secure origins.
bool IsRestrictedToSecureOrigins(content::PermissionType permission) {
return false;
}
class CefGeolocationCallbackImpl : public CefGeolocationCallback {
public:
typedef CefPermissionContext::PermissionDecidedCallback CallbackType;
explicit CefGeolocationCallbackImpl(const CallbackType& callback)
: callback_(callback) {}
void Continue(bool allow) override {
if (CEF_CURRENTLY_ON_UIT()) {
if (!callback_.is_null()) {
if (allow) {
content::GeolocationProvider::GetInstance()->
UserDidOptIntoLocationServices();
}
callback_.Run(allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
callback_.Reset();
}
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefGeolocationCallbackImpl::Continue, this, allow));
}
}
void Disconnect() {
callback_.Reset();
}
private:
CallbackType callback_;
IMPLEMENT_REFCOUNTING(CefGeolocationCallbackImpl);
DISALLOW_COPY_AND_ASSIGN(CefGeolocationCallbackImpl);
};
} // namespace
CefPermissionContext::CefPermissionContext(CefBrowserContext* profile)
: profile_(profile),
weak_ptr_factory_(this) {
}
bool CefPermissionContext::SupportsPermission(
content::PermissionType permission) {
// Only Geolocation permissions are currently supported.
return permission == content::PermissionType::GEOLOCATION;
}
void CefPermissionContext::RequestPermission(
content::PermissionType permission,
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
const BrowserPermissionCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DecidePermission(permission,
web_contents,
id,
requesting_frame.GetOrigin(),
web_contents->GetLastCommittedURL().GetOrigin(),
user_gesture,
callback);
}
void CefPermissionContext::CancelPermissionRequest(
content::PermissionType permission,
content::WebContents* web_contents,
const PermissionRequestID& id) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(permission == content::PermissionType::GEOLOCATION);
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())
handler->OnCancelGeolocationPermission(browser.get(), id.request_id());
}
}
}
void CefPermissionContext::ResetPermission(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
profile_->GetHostContentSettingsMap()->SetContentSetting(
ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
ContentSettingsPattern::FromURLNoWildcard(embedding_origin),
permission_util::PermissionTypeToContentSetting(permission),
std::string(),
CONTENT_SETTING_DEFAULT);
}
ContentSetting CefPermissionContext::GetPermissionStatus(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) const {
if (IsRestrictedToSecureOrigins(permission) &&
!content::IsOriginSecure(requesting_origin)) {
return CONTENT_SETTING_BLOCK;
}
return profile_->GetHostContentSettingsMap()->GetContentSetting(
requesting_origin,
embedding_origin,
permission_util::PermissionTypeToContentSetting(permission),
std::string());
}
void CefPermissionContext::DecidePermission(
content::PermissionType permission,
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
bool user_gesture,
const BrowserPermissionCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) {
NotifyPermissionSet(permission, id, requesting_origin, embedding_origin,
callback, false /* persist */, CONTENT_SETTING_BLOCK);
return;
}
if (IsRestrictedToSecureOrigins(permission) &&
!content::IsOriginSecure(requesting_origin)) {
NotifyPermissionSet(permission, id, requesting_origin, embedding_origin,
callback, false /* persist */, CONTENT_SETTING_BLOCK);
return;
}
ContentSetting content_setting =
profile_->GetHostContentSettingsMap()->
GetContentSettingAndMaybeUpdateLastUsage(
requesting_origin,
embedding_origin,
permission_util::PermissionTypeToContentSetting(permission),
std::string());
if (content_setting == CONTENT_SETTING_ALLOW ||
content_setting == CONTENT_SETTING_BLOCK) {
NotifyPermissionSet(permission, id, requesting_origin, embedding_origin,
callback, false /* persist */, content_setting);
return;
}
QueryPermission(
permission, id, requesting_origin, embedding_origin,
base::Bind(&CefPermissionContext::NotifyPermissionSet,
weak_ptr_factory_.GetWeakPtr(), permission, id,
requesting_origin, embedding_origin, callback,
false /* persist */));
}
void CefPermissionContext::QueryPermission(
content::PermissionType permission,
const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
const PermissionDecidedCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(permission == content::PermissionType::GEOLOCATION);
bool proceed = false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForFrame(id.render_process_id(),
id.render_frame_id());
if (browser.get()) {
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefGeolocationHandler> handler =
client->GetGeolocationHandler();
if (handler.get()) {
CefRefPtr<CefGeolocationCallbackImpl> callbackImpl(
new CefGeolocationCallbackImpl(callback));
// Notify the handler.
proceed = handler->OnRequestGeolocationPermission(
browser.get(), requesting_origin.spec(), id.request_id(),
callbackImpl.get());
if (!proceed)
callbackImpl->Disconnect();
}
}
}
if (!proceed) {
// Disallow geolocation access by default.
callback.Run(CONTENT_SETTING_BLOCK);
}
}
void CefPermissionContext::NotifyPermissionSet(
content::PermissionType permission,
const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
const BrowserPermissionCallback& callback,
bool persist,
ContentSetting content_setting) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (persist) {
UpdateContentSetting(permission, requesting_origin, embedding_origin,
content_setting);
}
if (content_setting == CONTENT_SETTING_DEFAULT) {
content_setting =
profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
permission_util::PermissionTypeToContentSetting(permission),
nullptr);
}
DCHECK_NE(content_setting, CONTENT_SETTING_DEFAULT);
callback.Run(content_setting);
}
void CefPermissionContext::UpdateContentSetting(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin,
ContentSetting content_setting) {
DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin());
DCHECK_EQ(embedding_origin, embedding_origin.GetOrigin());
DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
content_setting == CONTENT_SETTING_BLOCK);
profile_->GetHostContentSettingsMap()->SetContentSetting(
ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
ContentSettingsPattern::FromURLNoWildcard(embedding_origin),
permission_util::PermissionTypeToContentSetting(permission),
std::string(),
content_setting);
}

View File

@@ -0,0 +1,99 @@
// Copyright 2015 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_PERMISSIONS_PERMISSION_CONTEXT_H_
#define CEF_LIBCEF_BROWSER_PERMISSIONS_PERMISSION_CONTEXT_H_
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/permissions/permission_request_id.h"
#include "components/content_settings/core/common/content_settings.h"
class CefBrowserContext;
namespace content {
enum class PermissionType;
class WebContents;
}; // namespace content
// Based on chrome/browser/permissions/permission_context_base.h
class CefPermissionContext {
public:
explicit CefPermissionContext(CefBrowserContext* profile);
using BrowserPermissionCallback = base::Callback<void(ContentSetting)>;
using PermissionDecidedCallback = base::Callback<void(ContentSetting)>;
// Returns true if support exists for querying the embedder about the
// specified permission type.
bool SupportsPermission(content::PermissionType permission);
// The renderer is requesting permission to push messages.
// When the answer to a permission request has been determined, |callback|
// should be called with the result.
void RequestPermission(content::PermissionType permission,
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
const BrowserPermissionCallback& callback);
// Withdraw an existing permission request, no op if the permission request
// was already cancelled by some other means.
void CancelPermissionRequest(content::PermissionType permission,
content::WebContents* web_contents,
const PermissionRequestID& id);
// Resets the permission to its default value.
void ResetPermission(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin);
// Returns whether the permission has been granted, denied...
ContentSetting GetPermissionStatus(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) const;
private:
// Decide whether the permission should be granted.
// Calls PermissionDecided if permission can be decided non-interactively,
// or NotifyPermissionSet if permission decided by presenting an infobar.
void DecidePermission(content::PermissionType permission,
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
bool user_gesture,
const BrowserPermissionCallback& callback);
void QueryPermission(content::PermissionType permission,
const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
const PermissionDecidedCallback& callback);
void NotifyPermissionSet(content::PermissionType permission,
const PermissionRequestID& id,
const GURL& requesting_origin,
const GURL& embedding_origin,
const BrowserPermissionCallback& callback,
bool persist,
ContentSetting content_setting);
// Store the decided permission as a content setting.
void UpdateContentSetting(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin,
ContentSetting content_setting);
CefBrowserContext* profile_;
base::WeakPtrFactory<CefPermissionContext> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefPermissionContext);
};
#endif // CEF_LIBCEF_BROWSER_PERMISSIONS_PERMISSION_CONTEXT_H_

View File

@@ -0,0 +1,382 @@
// Copyright 2015 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/permissions/permission_manager.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/permissions/permission_util.h"
#include "base/callback.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
using content::PermissionStatus;
using content::PermissionType;
namespace {
// Helper method to convert ContentSetting to PermissionStatus.
PermissionStatus ContentSettingToPermissionStatus(ContentSetting setting) {
switch (setting) {
case CONTENT_SETTING_ALLOW:
case CONTENT_SETTING_SESSION_ONLY:
return content::PERMISSION_STATUS_GRANTED;
case CONTENT_SETTING_BLOCK:
return content::PERMISSION_STATUS_DENIED;
case CONTENT_SETTING_ASK:
return content::PERMISSION_STATUS_ASK;
case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT:
case CONTENT_SETTING_DEFAULT:
case CONTENT_SETTING_NUM_SETTINGS:
break;
}
NOTREACHED();
return content::PERMISSION_STATUS_DENIED;
}
// Helper method to convert PermissionStatus to ContentSetting.
ContentSetting PermissionStatusToContentSetting(PermissionStatus status) {
switch (status) {
case content::PERMISSION_STATUS_GRANTED:
return CONTENT_SETTING_ALLOW;
case content::PERMISSION_STATUS_DENIED:
return CONTENT_SETTING_BLOCK;
case content::PERMISSION_STATUS_ASK:
return CONTENT_SETTING_ASK;
}
NOTREACHED();
return CONTENT_SETTING_BLOCK;
}
// Wrap a callback taking a PermissionStatus to pass it as a callback taking a
// ContentSetting.
void ContentSettingToPermissionStatusCallbackWrapper(
const base::Callback<void(PermissionStatus)>& callback,
ContentSetting setting) {
callback.Run(ContentSettingToPermissionStatus(setting));
}
// Returns whether the permission has a constant PermissionStatus value (i.e.
// always approved or always denied).
bool IsConstantPermission(PermissionType type) {
switch (type) {
case PermissionType::MIDI:
return true;
default:
return false;
}
}
void PermissionRequestResponseCallbackWrapper(
const base::Callback<void(PermissionStatus)>& callback,
const std::vector<PermissionStatus>& vector) {
DCHECK_EQ(vector.size(), 1ul);
callback.Run(vector[0]);
}
// Function used for handling permission types which do not change their
// value i.e. they are always approved or always denied etc.
// CONTENT_SETTING_DEFAULT is returned if the permission needs further handling.
// This function should only be called when IsConstantPermission has returned
// true for the PermissionType.
ContentSetting GetContentSettingForConstantPermission(PermissionType type) {
DCHECK(IsConstantPermission(type));
switch (type) {
case PermissionType::MIDI:
return CONTENT_SETTING_ALLOW;
default:
return CONTENT_SETTING_DEFAULT;
}
}
PermissionStatus GetPermissionStatusForConstantPermission(PermissionType type) {
return ContentSettingToPermissionStatus(
GetContentSettingForConstantPermission(type));
}
} // anonymous namespace
class CefPermissionManager::PendingRequest {
public:
PendingRequest(content::RenderFrameHost* render_frame_host,
const std::vector<PermissionType> permissions,
const base::Callback<void(
const std::vector<PermissionStatus>&)>& callback)
: render_process_id_(render_frame_host->GetProcess()->GetID()),
render_frame_id_(render_frame_host->GetRoutingID()),
callback_(callback),
permissions_(permissions),
results_(permissions.size(), content::PERMISSION_STATUS_DENIED),
remaining_results_(permissions.size()) {
}
void SetPermissionStatus(int permission_id, PermissionStatus status) {
DCHECK(!IsComplete());
results_[permission_id] = status;
--remaining_results_;
}
bool IsComplete() const {
return remaining_results_ == 0;
}
int render_process_id() const { return render_process_id_; }
int render_frame_id() const { return render_frame_id_; }
const base::Callback<void(const std::vector<PermissionStatus>&)>
callback() const {
return callback_;
}
std::vector<PermissionType> permissions() const {
return permissions_;
}
std::vector<PermissionStatus> results() const {
return results_;
}
private:
int render_process_id_;
int render_frame_id_;
const base::Callback<void(const std::vector<PermissionStatus>&)> callback_;
std::vector<PermissionType> permissions_;
std::vector<PermissionStatus> results_;
size_t remaining_results_;
};
struct CefPermissionManager::Subscription {
PermissionType permission;
GURL requesting_origin;
GURL embedding_origin;
base::Callback<void(PermissionStatus)> callback;
ContentSetting current_value;
};
CefPermissionManager::CefPermissionManager(CefBrowserContext* profile)
: profile_(profile),
context_(profile),
weak_ptr_factory_(this) {
}
CefPermissionManager::~CefPermissionManager() {
if (!subscriptions_.IsEmpty())
profile_->GetHostContentSettingsMap()->RemoveObserver(this);
}
int CefPermissionManager::RequestPermission(
PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(PermissionStatus)>& callback) {
return RequestPermissions(
std::vector<PermissionType>(1, permission),
render_frame_host,
requesting_origin,
user_gesture,
base::Bind(&PermissionRequestResponseCallbackWrapper, callback));
}
int CefPermissionManager::RequestPermissions(
const std::vector<PermissionType>& permissions,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(
const std::vector<PermissionStatus>&)>& callback) {
if (permissions.empty()) {
callback.Run(std::vector<PermissionStatus>());
return kNoPendingOperation;
}
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin();
PendingRequest* pending_request = new PendingRequest(
render_frame_host, permissions, callback);
int request_id = pending_requests_.Add(pending_request);
const PermissionRequestID request(render_frame_host, request_id);
for (size_t i = 0; i < permissions.size(); ++i) {
const PermissionType permission = permissions[i];
if (IsConstantPermission(permission) ||
!context_.SupportsPermission(permission)) {
OnPermissionsRequestResponseStatus(request_id, i,
GetPermissionStatus(permission, requesting_origin, embedding_origin));
continue;
}
context_.RequestPermission(
permission, web_contents, request, requesting_origin, user_gesture,
base::Bind(&ContentSettingToPermissionStatusCallbackWrapper,
base::Bind(
&CefPermissionManager::OnPermissionsRequestResponseStatus,
weak_ptr_factory_.GetWeakPtr(), request_id, i)));
}
// The request might have been resolved already.
if (!pending_requests_.Lookup(request_id))
return kNoPendingOperation;
return request_id;
}
void CefPermissionManager::OnPermissionsRequestResponseStatus(
int request_id,
int permission_id,
PermissionStatus status) {
PendingRequest* pending_request = pending_requests_.Lookup(request_id);
pending_request->SetPermissionStatus(permission_id, status);
if (!pending_request->IsComplete())
return;
pending_request->callback().Run(pending_request->results());
pending_requests_.Remove(request_id);
}
void CefPermissionManager::CancelPermissionRequest(int request_id) {
PendingRequest* pending_request = pending_requests_.Lookup(request_id);
if (!pending_request)
return;
content::RenderFrameHost* render_frame_host =
content::RenderFrameHost::FromID(pending_request->render_process_id(),
pending_request->render_frame_id());
DCHECK(render_frame_host);
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
DCHECK(web_contents);
const PermissionRequestID request(pending_request->render_process_id(),
pending_request->render_frame_id(),
request_id);
for (PermissionType permission : pending_request->permissions()) {
if (!context_.SupportsPermission(permission))
continue;
context_.CancelPermissionRequest(permission, web_contents, request);
}
pending_requests_.Remove(request_id);
}
void CefPermissionManager::ResetPermission(PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
if (!context_.SupportsPermission(permission))
return;
context_.ResetPermission(permission, requesting_origin, embedding_origin);
}
PermissionStatus CefPermissionManager::GetPermissionStatus(
PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
if (IsConstantPermission(permission))
return GetPermissionStatusForConstantPermission(permission);
if (!context_.SupportsPermission(permission))
return content::PERMISSION_STATUS_DENIED;
return ContentSettingToPermissionStatus(
context_.GetPermissionStatus(permission, requesting_origin,
embedding_origin));
}
void CefPermissionManager::RegisterPermissionUsage(
PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
// This is required because constant permissions don't have a
// ContentSettingsType.
if (IsConstantPermission(permission))
return;
profile_->GetHostContentSettingsMap()->UpdateLastUsage(
requesting_origin,
embedding_origin,
permission_util::PermissionTypeToContentSetting(permission));
}
int CefPermissionManager::SubscribePermissionStatusChange(
PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin,
const base::Callback<void(PermissionStatus)>& callback) {
if (subscriptions_.IsEmpty())
profile_->GetHostContentSettingsMap()->AddObserver(this);
Subscription* subscription = new Subscription();
subscription->permission = permission;
subscription->requesting_origin = requesting_origin;
subscription->embedding_origin = embedding_origin;
subscription->callback = callback;
subscription->current_value = PermissionStatusToContentSetting(
GetPermissionStatus(permission,
subscription->requesting_origin,
subscription->embedding_origin));
return subscriptions_.Add(subscription);
}
void CefPermissionManager::UnsubscribePermissionStatusChange(
int subscription_id) {
// Whether |subscription_id| is known will be checked by the Remove() call.
subscriptions_.Remove(subscription_id);
if (subscriptions_.IsEmpty())
profile_->GetHostContentSettingsMap()->RemoveObserver(this);
}
void CefPermissionManager::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
std::string resource_identifier) {
std::list<base::Closure> callbacks;
for (SubscriptionsMap::iterator iter(&subscriptions_);
!iter.IsAtEnd(); iter.Advance()) {
Subscription* subscription = iter.GetCurrentValue();
if (permission_util::PermissionTypeToContentSetting(
subscription->permission) != content_type) {
continue;
}
if (primary_pattern.IsValid() &&
!primary_pattern.Matches(subscription->requesting_origin))
continue;
if (secondary_pattern.IsValid() &&
!secondary_pattern.Matches(subscription->embedding_origin))
continue;
ContentSetting new_value = PermissionStatusToContentSetting(
GetPermissionStatus(subscription->permission,
subscription->requesting_origin,
subscription->embedding_origin));
if (subscription->current_value == new_value)
continue;
subscription->current_value = new_value;
// Add the callback to |callbacks| which will be run after the loop to
// prevent re-entrance issues.
callbacks.push_back(
base::Bind(subscription->callback,
ContentSettingToPermissionStatus(new_value)));
}
for (const auto& callback : callbacks)
callback.Run();
}

View File

@@ -0,0 +1,100 @@
// Copyright 2015 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_PERMISSIONS_PERMISSION_MANAGER_H_
#define CEF_LIBCEF_BROWSER_PERMISSIONS_PERMISSION_MANAGER_H_
#include "libcef/browser/permissions/permission_context.h"
#include "base/callback_forward.h"
#include "base/id_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/content_settings/core/browser/content_settings_observer.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/permission_manager.h"
class CefBrowserContext;
namespace content {
enum class PermissionType;
class WebContents;
}; // namespace content
// Implementation based on chrome/browser/permissions/permission_manager.h
class CefPermissionManager : public KeyedService,
public content::PermissionManager,
public content_settings::Observer {
public:
explicit CefPermissionManager(CefBrowserContext* profile);
~CefPermissionManager() override;
// content::CefPermissionManager implementation.
int RequestPermission(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(content::PermissionStatus)>& callback) override;
int RequestPermissions(
const std::vector<content::PermissionType>& permissions,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(
const std::vector<content::PermissionStatus>&)>& callback) override;
void CancelPermissionRequest(int request_id) override;
void ResetPermission(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
content::PermissionStatus GetPermissionStatus(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
void RegisterPermissionUsage(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
int SubscribePermissionStatusChange(
content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin,
const base::Callback<void(content::PermissionStatus)>& callback) override;
void UnsubscribePermissionStatusChange(int subscription_id) override;
private:
class PendingRequest;
using PendingRequestsMap = IDMap<PendingRequest, IDMapOwnPointer>;
struct Subscription;
using SubscriptionsMap = IDMap<Subscription, IDMapOwnPointer>;
// Called when a permission was decided for a given PendingRequest. The
// PendingRequest is identified by its |request_id| and the permission is
// identified by its |permission_id|. If the PendingRequest contains more than
// one permission, it will wait for the remaining permissions to be resolved.
// When all the permissions have been resolved, the PendingRequest's callback
// is run.
void OnPermissionsRequestResponseStatus(
int request_id,
int permission_id,
content::PermissionStatus status);
// content_settings::Observer implementation.
void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
std::string resource_identifier) override;
CefBrowserContext* profile_;
PendingRequestsMap pending_requests_;
SubscriptionsMap subscriptions_;
CefPermissionContext context_;
base::WeakPtrFactory<CefPermissionManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefPermissionManager);
};
#endif // CEF_LIBCEF_BROWSER_PERMISSIONS_PERMISSION_MANAGER_H_

View File

@@ -0,0 +1,49 @@
// Copyright 2015 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/permissions/permission_util.h"
#include "base/logging.h"
using content::PermissionType;
namespace permission_util {
ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) {
switch (permission) {
case PermissionType::MIDI_SYSEX:
return CONTENT_SETTINGS_TYPE_MIDI_SYSEX;
case PermissionType::PUSH_MESSAGING:
return CONTENT_SETTINGS_TYPE_PUSH_MESSAGING;
case PermissionType::NOTIFICATIONS:
return CONTENT_SETTINGS_TYPE_NOTIFICATIONS;
case PermissionType::GEOLOCATION:
return CONTENT_SETTINGS_TYPE_GEOLOCATION;
case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
return CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER;
#else
NOTIMPLEMENTED();
break;
#endif
case PermissionType::DURABLE_STORAGE:
return CONTENT_SETTINGS_TYPE_DURABLE_STORAGE;
case PermissionType::MIDI:
// This will hit the NOTREACHED below.
break;
case PermissionType::AUDIO_CAPTURE:
return CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC;
case PermissionType::VIDEO_CAPTURE:
return CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA;
case PermissionType::NUM:
// This will hit the NOTREACHED below.
break;
}
NOTREACHED() << "Unknown content setting for permission "
<< static_cast<int>(permission);
return CONTENT_SETTINGS_TYPE_DEFAULT;
}
} // namespace permission_util

View File

@@ -0,0 +1,19 @@
// Copyright 2015 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_PERMISSIONS_PERMISSION_UTIL_H_
#define CEF_LIBCEF_BROWSER_PERMISSIONS_PERMISSION_UTIL_H_
#include "components/content_settings/core/common/content_settings_types.h"
#include "content/public/browser/permission_type.h"
namespace permission_util {
// Helper method to convert PermissionType to ContentSettingType.
ContentSettingsType PermissionTypeToContentSetting(
content::PermissionType permission);
} // namespace permission_util
#endif // CEF_LIBCEF_BROWSER_PERMISSIONS_PERMISSION_UTIL_H_

View File

@@ -297,9 +297,9 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
// to actually spool the pages, only to have the renderer generate them. Run
// a message loop until we get our signal that the print job is satisfied.
// PrintJob will send a ALL_PAGES_REQUESTED after having received all the
// pages it needs. MessageLoop::current()->Quit() will be called as soon as
// print_job_->document()->IsComplete() is true on either ALL_PAGES_REQUESTED
// or in DidPrintPage(). The check is done in
// pages it needs. MessageLoop::current()->QuitWhenIdle() will be called as
// soon as print_job_->document()->IsComplete() is true on either
// ALL_PAGES_REQUESTED or in DidPrintPage(). The check is done in
// ShouldQuitFromInnerMessageLoop().
// BLOCKS until all the pages are received. (Need to enable recursive task)
if (!RunInnerMessageLoop()) {
@@ -318,7 +318,7 @@ void PrintViewManagerBase::ShouldQuitFromInnerMessageLoop() {
inside_inner_message_loop_) {
// We are in a message loop created by RenderAllMissingPagesNow. Quit from
// it.
base::MessageLoop::current()->Quit();
base::MessageLoop::current()->QuitWhenIdle();
inside_inner_message_loop_ = false;
}
}
@@ -424,9 +424,9 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
// memory-bound.
static const int kPrinterSettingsTimeout = 60000;
base::OneShotTimer quit_timer;
quit_timer.Start(FROM_HERE,
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
base::MessageLoop::current(), &base::MessageLoop::Quit);
quit_timer.Start(
FROM_HERE, TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
inside_inner_message_loop_ = true;
@@ -477,8 +477,9 @@ bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
}
bool PrintViewManagerBase::PrintNowInternal(IPC::Message* message) {
// Don't print / print preview interstitials.
if (web_contents()->ShowingInterstitialPage()) {
// Don't print / print preview interstitials or crashed tabs.
if (web_contents()->ShowingInterstitialPage() ||
web_contents()->IsCrashed()) {
delete message;
return false;
}

View File

@@ -266,7 +266,7 @@ class CefCopyFrameGenerator {
gl_helper->CropScaleReadbackAndCleanMailbox(
texture_mailbox.mailbox(),
texture_mailbox.sync_point(),
texture_mailbox.sync_token(),
result_size,
gfx::Rect(result_size),
result_size,
@@ -290,14 +290,15 @@ class CefCopyFrameGenerator {
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
bool result) {
// This method may be called after the view has been deleted.
uint32 sync_point = 0;
gpu::SyncToken sync_token;
if (result) {
content::GLHelper* gl_helper =
content::ImageTransportFactory::GetInstance()->GetGLHelper();
sync_point = gl_helper->InsertSyncPoint();
if (gl_helper)
sync_token = gpu::SyncToken(gl_helper->InsertSyncPoint());
}
bool lost_resource = sync_point == 0;
release_callback->Run(sync_point, lost_resource);
const bool lost_resource = !sync_token.HasData();
release_callback->Run(sync_token, lost_resource);
if (generator) {
generator->CopyFromCompositingSurfaceFinished(
@@ -461,7 +462,7 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
render_widget_host_->SetView(this);
// CefBrowserHostImpl might not be created at this time for popups.
if (render_widget_host_->IsRenderView()) {
if (content::RenderViewHost::From(render_widget_host_)) {
browser_impl_ = CefBrowserHostImpl::GetBrowserForHost(
content::RenderViewHost::From(render_widget_host_));
}
@@ -474,7 +475,7 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
compositor_.reset(
new ui::Compositor(content::GetContextFactory(),
base::ThreadTaskRunnerHandle::Get()));
compositor_->SetAcceleratedWidgetAndStartCompositor(compositor_widget_);
compositor_->SetAcceleratedWidget(compositor_widget_);
#endif
compositor_->SetDelegate(this);
compositor_->SetRootLayer(root_layer_.get());
@@ -947,6 +948,14 @@ content::BrowserAccessibilityManager*
return NULL;
}
void CefRenderWidgetHostViewOSR::LockCompositingSurface() {
NOTIMPLEMENTED();
}
void CefRenderWidgetHostViewOSR::UnlockCompositingSurface() {
NOTIMPLEMENTED();
}
#if defined(TOOLKIT_VIEWS) || defined(USE_AURA)
void CefRenderWidgetHostViewOSR::ShowDisambiguationPopup(
const gfx::Rect& rect_pixels,

View File

@@ -167,6 +167,8 @@ class CefRenderWidgetHostViewOSR
content::BrowserAccessibilityManager*
CreateBrowserAccessibilityManager(
content::BrowserAccessibilityDelegate* delegate) override;
void LockCompositingSurface() override;
void UnlockCompositingSurface() override;
#if defined(TOOLKIT_VIEWS) || defined(USE_AURA)
void ShowDisambiguationPopup(const gfx::Rect& rect_pixels,
@@ -193,12 +195,9 @@ class CefRenderWidgetHostViewOSR
#if defined(OS_MACOSX)
// AcceleratedWidgetMacNSView implementation.
NSView* AcceleratedWidgetGetNSView() const override;
bool AcceleratedWidgetShouldIgnoreBackpressure() const override;
void AcceleratedWidgetGetVSyncParameters(
base::TimeTicks* timebase, base::TimeDelta* interval) const override;
void AcceleratedWidgetSwapCompleted(
const std::vector<ui::LatencyInfo>& latency_info) override;
void AcceleratedWidgetHitError() override;
void AcceleratedWidgetSwapCompleted() override;
#endif // defined(OS_MACOSX)
bool OnMessageReceived(const IPC::Message& msg) override;

View File

@@ -117,31 +117,13 @@ NSView* CefRenderWidgetHostViewOSR::AcceleratedWidgetGetNSView() const {
return [window_ contentView];
}
bool CefRenderWidgetHostViewOSR::AcceleratedWidgetShouldIgnoreBackpressure()
const {
return true;
}
void CefRenderWidgetHostViewOSR::AcceleratedWidgetGetVSyncParameters(
base::TimeTicks* timebase, base::TimeDelta* interval) const {
*timebase = base::TimeTicks();
*interval = base::TimeDelta();
}
void CefRenderWidgetHostViewOSR::AcceleratedWidgetSwapCompleted(
const std::vector<ui::LatencyInfo>& all_latency_info) {
if (!render_widget_host_)
return;
for (auto latency_info : all_latency_info) {
latency_info.AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
render_widget_host_->FrameSwapped(latency_info);
}
}
void CefRenderWidgetHostViewOSR::AcceleratedWidgetHitError() {
// Request a new frame be drawn.
browser_compositor_->compositor()->ScheduleFullRedraw();
void CefRenderWidgetHostViewOSR::AcceleratedWidgetSwapCompleted() {
}
CefTextInputContext CefRenderWidgetHostViewOSR::GetNSTextInputContext() {

View File

@@ -48,5 +48,5 @@ bool CefEndTracing(const CefString& tracing_file,
}
int64 CefNowFromSystemTraceTime() {
return base::TraceTicks::Now().ToInternalValue();
return base::TimeTicks::Now().ToInternalValue();
}

View File

@@ -194,14 +194,14 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
make_scoped_ptr<net::HttpServerProperties>(
new net::HttpServerPropertiesImpl));
net::HttpCache::DefaultBackend* main_backend =
scoped_ptr<net::HttpCache::DefaultBackend> main_backend(
new net::HttpCache::DefaultBackend(
cache_path.empty() ? net::MEMORY_CACHE : net::DISK_CACHE,
net::CACHE_BACKEND_DEFAULT,
cache_path,
0,
BrowserThread::GetMessageLoopProxyForThread(
BrowserThread::CACHE));
BrowserThread::CACHE)));
net::HttpNetworkSession::Params network_session_params;
network_session_params.host_resolver =
@@ -225,10 +225,12 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
network_session_params.ignore_certificate_errors =
settings_.ignore_certificate_errors ? true : false;
scoped_ptr<net::HttpCache> main_cache(
new net::HttpCache(network_session_params,
main_backend));
storage_->set_http_transaction_factory(main_cache.Pass());
storage_->set_http_network_session(
make_scoped_ptr(new net::HttpNetworkSession(network_session_params)));
storage_->set_http_transaction_factory(make_scoped_ptr(
new net::HttpCache(storage_->http_network_session(),
main_backend.Pass(),
true /* set_up_quic_server_info */)));
#if !defined(DISABLE_FTP_SUPPORT)
ftp_transaction_factory_.reset(

View File

@@ -123,7 +123,7 @@ content::RenderWidgetHostViewBase* CefWebContentsViewOSR::CreateViewForWidget(
guest_->embedder_web_contents();
CefRenderWidgetHostViewOSR* embedder_host_view =
static_cast<CefRenderWidgetHostViewOSR*>(
embedder_web_contents->GetRenderViewHost()->GetView());
embedder_web_contents->GetRenderViewHost()->GetWidget()->GetView());
CefRenderWidgetHostViewOSR* platform_widget =
new CefRenderWidgetHostViewOSR(render_widget_host, embedder_host_view);

View File

@@ -27,7 +27,6 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/widevine_cdm_constants.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/render_process_host.h"
@@ -193,8 +192,10 @@ void OverridePepperFlashSystemPluginPath() {
return;
#endif
PathService::Override(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
plugin_filename);
if (!plugin_filename.empty()) {
PathService::Override(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
plugin_filename);
}
}
#if defined(OS_LINUX)
@@ -566,8 +567,9 @@ void CefMainDelegate::PreSandboxStartup() {
}
#if defined(WIDEVINE_CDM_IS_COMPONENT)
if (command_line->HasSwitch(switches::kEnableWidevineCdm)) {
PathService::Override(chrome::DIR_COMPONENT_WIDEVINE_CDM,
user_data_path.Append(kWidevineCdmBaseDirectory));
PathService::Override(
chrome::DIR_COMPONENT_WIDEVINE_CDM,
user_data_path.Append(FILE_PATH_LITERAL("WidevineCDM")));
}
#endif // defined(WIDEVINE_CDM_IS_COMPONENT)
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)

View File

@@ -143,6 +143,9 @@ CefString CefURIDecode(const CefString& text,
bool CefParseCSSColor(const CefString& string,
bool strict,
cef_color_t& color) {
// Blink types depend on PartitionAlloc. Safe to call multiple times.
webkit_glue::InitializePartitionAlloc();
return webkit_glue::ParseCSSColor(
blink::WebString::fromUTF8(string.ToString().data()), strict, color);
}

View File

@@ -14,7 +14,6 @@
#include "libcef/common/request_impl.h"
#include "libcef/common/values_impl.h"
#include "libcef/renderer/browser_impl.h"
#include "libcef/renderer/extensions/extensions_dispatcher_delegate.h"
#include "libcef/renderer/extensions/extensions_renderer_client.h"
#include "libcef/renderer/extensions/print_web_view_helper_delegate.h"
#include "libcef/renderer/media/cef_key_systems.h"
@@ -34,12 +33,10 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_process_policy.h"
#include "chrome/common/pepper_permission_util.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/extensions/resource_request_policy.h"
#include "chrome/renderer/loadtimes_extension_bindings.h"
#include "chrome/renderer/pepper/chrome_pdf_print_client.h"
#include "chrome/renderer/spellchecker/spellcheck.h"
@@ -55,31 +52,22 @@
#include "content/public/child/child_thread.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/plugin_instance_throttler.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_visitor.h"
#include "content/renderer/render_frame_impl.h"
#include "extensions/common/constants.h"
#include "extensions/common/switches.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/dispatcher_delegate.h"
#include "extensions/renderer/extension_frame_helper.h"
#include "extensions/renderer/extension_helper.h"
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
#include "extensions/renderer/renderer_extension_registry.h"
#include "ipc/ipc_sync_channel.h"
#include "media/base/media.h"
#include "third_party/WebKit/public/platform/WebPrerenderingSupport.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "third_party/WebKit/public/web/WebPrerendererClient.h"
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
@@ -117,14 +105,6 @@ class CefPrerendererClient : public content::RenderViewObserver,
void willAddPrerender(blink::WebPrerender* prerender) override {}
};
void IsGuestViewApiAvailableToScriptContext(
bool* api_is_available,
extensions::ScriptContext* context) {
if (context->GetAvailability("guestViewInternal").is_available()) {
*api_is_available = true;
}
}
void AppendParams(const std::vector<base::string16>& additional_names,
const std::vector<base::string16>& additional_values,
blink::WebVector<blink::WebString>* existing_names,
@@ -165,73 +145,20 @@ std::string GetPluginInstancePosterAttribute(
return std::string();
}
bool IsStandaloneExtensionProcess() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
extensions::switches::kExtensionProcess);
}
bool CrossesExtensionExtents(
blink::WebLocalFrame* frame,
const GURL& new_url,
bool is_extension_url,
bool is_initial_navigation) {
DCHECK(!frame->parent());
GURL old_url(frame->document().url());
extensions::RendererExtensionRegistry* extension_registry =
extensions::RendererExtensionRegistry::Get();
// If old_url is still empty and this is an initial navigation, then this is
// a window.open operation. We should look at the opener URL. Note that the
// opener is a local frame in this case.
if (is_initial_navigation && old_url.is_empty() && frame->opener()) {
blink::WebLocalFrame* opener_frame = frame->opener()->toWebLocalFrame();
// If we're about to open a normal web page from a same-origin opener stuck
// in an extension process, we want to keep it in process to allow the
// opener to script it.
blink::WebDocument opener_document = opener_frame->document();
blink::WebSecurityOrigin opener_origin = opener_document.securityOrigin();
bool opener_is_extension_url = !opener_origin.isUnique() &&
extension_registry->GetExtensionOrAppByURL(
opener_document.url()) != NULL;
if (!is_extension_url &&
!opener_is_extension_url &&
IsStandaloneExtensionProcess() &&
opener_origin.canRequest(blink::WebURL(new_url)))
return false;
// In all other cases, we want to compare against the URL that determines
// the type of process. In default Chrome, that's the URL of the opener's
// top frame and not the opener frame itself. In --site-per-process, we
// can use the opener frame itself.
// TODO(nick): Either wire this up to SiteIsolationPolicy, or to state on
// |opener_frame|/its ancestors.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSitePerProcess) ||
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kIsolateExtensions))
old_url = opener_frame->document().url();
else
old_url = opener_frame->top()->document().url();
}
// Only consider keeping non-app URLs in an app process if this window
// has an opener (in which case it might be an OAuth popup that tries to
// script an iframe within the app).
bool should_consider_workaround = !!frame->opener();
return extensions::CrossesExtensionProcessBoundary(
*extension_registry->GetMainThreadExtensionSet(), old_url, new_url,
should_consider_workaround);
}
} // namespace
CefContentRendererClient::CefContentRendererClient()
: devtools_agent_count_(0),
uncaught_exception_stack_size_(0),
single_process_cleanup_complete_(false) {
if (extensions::ExtensionsEnabled()) {
extensions_client_.reset(new extensions::CefExtensionsClient);
extensions::ExtensionsClient::Set(extensions_client_.get());
extensions_renderer_client_.reset(
new extensions::CefExtensionsRendererClient);
extensions::ExtensionsRendererClient::Set(
extensions_renderer_client_.get());
}
}
CefContentRendererClient::~CefContentRendererClient() {
@@ -464,30 +391,8 @@ void CefContentRendererClient::RenderThreadStarted() {
pdf::PepperPDFHost::SetPrintClient(pdf_print_client_.get());
}
if (extensions::ExtensionsEnabled()) {
extensions_client_.reset(new extensions::CefExtensionsClient);
extensions::ExtensionsClient::Set(extensions_client_.get());
extensions_renderer_client_.reset(
new extensions::CefExtensionsRendererClient);
extensions::ExtensionsRendererClient::Set(
extensions_renderer_client_.get());
extension_dispatcher_delegate_.reset(
new extensions::CefExtensionsDispatcherDelegate());
// Must be initialized after ExtensionsRendererClient.
extension_dispatcher_.reset(
new extensions::Dispatcher(extension_dispatcher_delegate_.get()));
thread->AddObserver(extension_dispatcher_.get());
guest_view_container_dispatcher_.reset(
new extensions::ExtensionsGuestViewContainerDispatcher());
thread->AddObserver(guest_view_container_dispatcher_.get());
resource_request_policy_.reset(
new extensions::ResourceRequestPolicy(extension_dispatcher_.get()));
}
if (extensions::ExtensionsEnabled())
extensions_renderer_client_->RenderThreadStarted();
// Notify the render process handler.
CefRefPtr<CefApp> application = CefContentClient::Get()->application();
@@ -511,11 +416,8 @@ void CefContentRendererClient::RenderFrameCreated(
new CefRenderFrameObserver(render_frame);
new CefPepperHelper(render_frame);
if (extensions::ExtensionsEnabled()) {
new extensions::ExtensionFrameHelper(render_frame,
extension_dispatcher_.get());
extension_dispatcher_->OnRenderFrameCreated(render_frame);
}
if (extensions::ExtensionsEnabled())
extensions_renderer_client_->RenderFrameCreated(render_frame);
BrowserCreated(render_frame->GetRenderView(), render_frame);
}
@@ -528,9 +430,8 @@ void CefContentRendererClient::RenderViewCreated(
make_scoped_ptr<printing::PrintWebViewHelper::Delegate>(
new extensions::CefPrintWebViewHelperDelegate()));
if (extensions::ExtensionsEnabled()) {
new extensions::ExtensionHelper(render_view, extension_dispatcher_.get());
}
if (extensions::ExtensionsEnabled())
extensions_renderer_client_->RenderViewCreated(render_view);
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@@ -545,26 +446,19 @@ bool CefContentRendererClient::OverrideCreatePlugin(
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) {
if (!extensions::ExtensionsEnabled())
return false;
// Based on ChromeContentRendererClient::OverrideCreatePlugin.
std::string orig_mime_type = params.mimeType.utf8();
if (orig_mime_type == content::kBrowserPluginMimeType) {
bool guest_view_api_available = false;
extension_dispatcher_->script_context_set().ForEach(
render_frame,
base::Bind(&IsGuestViewApiAvailableToScriptContext,
&guest_view_api_available));
if (guest_view_api_available)
return false;
if (extensions::ExtensionsEnabled() &&
!extensions_renderer_client_->OverrideCreatePlugin(render_frame,
params)) {
return false;
}
GURL url(params.url);
CefViewHostMsg_GetPluginInfo_Output output;
blink::WebString top_origin = frame->top()->securityOrigin().toString();
render_frame->Send(new CefViewHostMsg_GetPluginInfo(
render_frame->GetRoutingID(), url, frame->top()->document().url(),
orig_mime_type, &output));
render_frame->GetRoutingID(), url, GURL(top_origin), orig_mime_type,
&output));
*plugin = CreatePlugin(render_frame, frame, params, output);
return true;
@@ -572,7 +466,7 @@ bool CefContentRendererClient::OverrideCreatePlugin(
bool CefContentRendererClient::HandleNavigation(
content::RenderFrame* render_frame,
content::DocumentState* document_state,
bool is_content_initiated,
int opener_id,
blink::WebFrame* frame,
const blink::WebURLRequest& request,
@@ -644,42 +538,8 @@ bool CefContentRendererClient::ShouldFork(blink::WebLocalFrame* frame,
return false;
if (extensions::ExtensionsEnabled()) {
const extensions::RendererExtensionRegistry* extension_registry =
extensions::RendererExtensionRegistry::Get();
// Determine if the new URL is an extension (excluding bookmark apps).
const extensions::Extension* new_url_extension =
extensions::GetNonBookmarkAppExtension(
*extension_registry->GetMainThreadExtensionSet(), url);
bool is_extension_url = !!new_url_extension;
// If the navigation would cross an app extent boundary, we also need
// to defer to the browser to ensure process isolation. This is not
// necessary for server redirects, which will be transferred to a new
// process by the browser process when they are ready to commit. It is
// necessary for client redirects, which won't be transferred in the same
// way.
if (!is_server_redirect &&
CrossesExtensionExtents(frame, url, is_extension_url,
is_initial_navigation)) {
// Include the referrer in this case since we're going from a hosted web
// page. (the packaged case is handled previously by the extension
// navigation test)
*send_referrer = true;
return true;
}
// If this is a reload, check whether it has the wrong process type. We
// should send it to the browser if it's an extension URL (e.g., hosted app)
// in a normal process, or if it's a process for an extension that has been
// uninstalled. Without --site-per-process mode, we never fork processes
// for subframes, so this check only makes sense for top-level frames.
// TODO(alexmos,nasko): Figure out how this check should work when reloading
// subframes in --site-per-process mode.
if (!frame->parent() && frame->document().url() == url) {
if (is_extension_url != IsStandaloneExtensionProcess())
return true;
}
return extensions::CefExtensionsRendererClient::ShouldFork(
frame, url, is_initial_navigation, is_server_redirect, send_referrer);
}
return false;
@@ -692,21 +552,8 @@ bool CefContentRendererClient::WillSendRequest(
const GURL& first_party_for_cookies,
GURL* new_url) {
if (extensions::ExtensionsEnabled()) {
// Check whether the request should be allowed. If not allowed, we reset the
// URL to something invalid to prevent the request and cause an error.
if (url.SchemeIs(extensions::kExtensionScheme) &&
!resource_request_policy_->CanRequestResource(url, frame,
transition_type)) {
*new_url = GURL(chrome::kExtensionInvalidRequestURL);
return true;
}
if (url.SchemeIs(extensions::kExtensionResourceScheme) &&
!resource_request_policy_->CanRequestExtensionResourceScheme(url,
frame)) {
*new_url = GURL(chrome::kExtensionResourceInvalidRequestURL);
return true;
}
return extensions_renderer_client_->WillSendRequest(frame, transition_type,
url, new_url);
}
return false;
@@ -718,12 +565,8 @@ CefContentRendererClient::CreateBrowserPluginDelegate(
const std::string& mime_type,
const GURL& original_url) {
DCHECK(extensions::ExtensionsEnabled());
if (mime_type == content::kBrowserPluginMimeType) {
return new extensions::ExtensionsGuestViewContainer(render_frame);
} else {
return new extensions::MimeHandlerViewContainer(
render_frame, mime_type, original_url);
}
return extensions::CefExtensionsRendererClient::CreateBrowserPluginDelegate(
render_frame, mime_type, original_url);
}
void CefContentRendererClient::AddKeySystems(
@@ -787,6 +630,7 @@ blink::WebPlugin* CefContentRendererClient::CreatePlugin(
params.mimeType = blink::WebString::fromUTF8(actual_mime_type.c_str());
}
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
auto create_blocked_plugin =
[&render_frame, &frame, &params, &info, &identifier, &group_name](
int template_id, const base::string16& message) {
@@ -806,11 +650,26 @@ blink::WebPlugin* CefContentRendererClient::CreatePlugin(
// CefContentRendererClient::CreatePlugin instead, to
// reduce the chance of future regressions.
bool is_prerendering = false;
bool power_saver_enabled =
bool is_flash =
info.name == base::ASCIIToUTF16(content::kFlashPluginName);
std::string override_for_testing = command_line->GetSwitchValueASCII(
switches::kOverridePluginPowerSaverForTesting);
// This feature has only been tested throughly with Flash thus far.
// It is also enabled for the Power Saver test plugin for browser tests.
bool can_throttle_plugin_type =
is_flash || override_for_testing == "ignore-list";
bool power_saver_setting_on =
status ==
CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent;
CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent;
bool power_saver_enabled =
override_for_testing == "always" ||
(power_saver_setting_on && can_throttle_plugin_type);
bool blocked_for_background_tab =
render_frame->IsHidden() && power_saver_enabled;
power_saver_enabled && render_frame->IsHidden();
PlaceholderPosterInfo poster_info;
if (power_saver_enabled) {

View File

@@ -21,6 +21,7 @@
#include "content/public/renderer/content_renderer_client.h"
namespace extensions {
class CefExtensionsRendererClient;
class Dispatcher;
class DispatcherDelegate;
class ExtensionsClient;
@@ -90,7 +91,7 @@ class CefContentRendererClient : public content::ContentRendererClient,
const blink::WebPluginParams& params,
blink::WebPlugin** plugin) override;
bool HandleNavigation(content::RenderFrame* render_frame,
content::DocumentState* document_state,
bool is_content_initiated,
int opener_id,
blink::WebFrame* frame,
const blink::WebURLRequest& request,
@@ -149,12 +150,8 @@ class CefContentRendererClient : public content::ContentRendererClient,
scoped_ptr<ChromePDFPrintClient> pdf_print_client_;
scoped_ptr<extensions::ExtensionsClient> extensions_client_;
scoped_ptr<extensions::ExtensionsRendererClient> extensions_renderer_client_;
scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_;
scoped_ptr<extensions::Dispatcher> extension_dispatcher_;
scoped_ptr<extensions::ExtensionsGuestViewContainerDispatcher>
guest_view_container_dispatcher_;
scoped_ptr<extensions::ResourceRequestPolicy> resource_request_policy_;
scoped_ptr<extensions::CefExtensionsRendererClient>
extensions_renderer_client_;
int devtools_agent_count_;
int uncaught_exception_stack_size_;

View File

@@ -4,10 +4,111 @@
#include "libcef/renderer/extensions/extensions_renderer_client.h"
#include "libcef/common/cef_messages.h"
#include "libcef/renderer/extensions/extensions_dispatcher_delegate.h"
#include "libcef/renderer/render_process_observer.h"
#include "base/command_line.h"
#include "chrome/common/extensions/extension_process_policy.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/resource_request_policy.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "extensions/common/constants.h"
#include "extensions/common/switches.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/extension_frame_helper.h"
#include "extensions/renderer/extension_helper.h"
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
#include "extensions/renderer/renderer_extension_registry.h"
#include "extensions/renderer/script_context.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
namespace extensions {
namespace {
bool IsStandaloneExtensionProcess() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
extensions::switches::kExtensionProcess);
}
void IsGuestViewApiAvailableToScriptContext(
bool* api_is_available,
extensions::ScriptContext* context) {
if (context->GetAvailability("guestViewInternal").is_available()) {
*api_is_available = true;
}
}
// Returns true if the frame is navigating to an URL either into or out of an
// extension app's extent.
bool CrossesExtensionExtents(blink::WebLocalFrame* frame,
const GURL& new_url,
bool is_extension_url,
bool is_initial_navigation) {
DCHECK(!frame->parent());
GURL old_url(frame->document().url());
extensions::RendererExtensionRegistry* extension_registry =
extensions::RendererExtensionRegistry::Get();
// If old_url is still empty and this is an initial navigation, then this is
// a window.open operation. We should look at the opener URL. Note that the
// opener is a local frame in this case.
if (is_initial_navigation && old_url.is_empty() && frame->opener()) {
blink::WebLocalFrame* opener_frame = frame->opener()->toWebLocalFrame();
// We usually want to compare against the URL that determines the type of
// process. In default Chrome, that's the URL of the opener's top frame and
// not the opener frame itself. In --site-per-process, we can use the
// opener frame itself.
// TODO(nick): Either wire this up to SiteIsolationPolicy, or to state on
// |opener_frame|/its ancestors.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kSitePerProcess) ||
extensions::IsIsolateExtensionsEnabled())
old_url = opener_frame->document().url();
else
old_url = opener_frame->top()->document().url();
// If we're about to open a normal web page from a same-origin opener stuck
// in an extension process (other than the Chrome Web Store), we want to
// keep it in process to allow the opener to script it.
blink::WebDocument opener_document = opener_frame->document();
blink::WebSecurityOrigin opener_origin = opener_document.securityOrigin();
bool opener_is_extension_url = !opener_origin.isUnique() &&
extension_registry->GetExtensionOrAppByURL(
opener_document.url()) != nullptr;
const extensions::Extension* opener_top_extension =
extension_registry->GetExtensionOrAppByURL(old_url);
bool opener_is_web_store =
opener_top_extension &&
opener_top_extension->id() == extensions::kWebStoreAppId;
if (!is_extension_url && !opener_is_extension_url && !opener_is_web_store &&
IsStandaloneExtensionProcess() &&
opener_origin.canRequest(blink::WebURL(new_url)))
return false;
}
// Only consider keeping non-app URLs in an app process if this window
// has an opener (in which case it might be an OAuth popup that tries to
// script an iframe within the app).
bool should_consider_workaround = !!frame->opener();
return extensions::CrossesExtensionProcessBoundary(
*extension_registry->GetMainThreadExtensionSet(), old_url, new_url,
should_consider_workaround);
}
} // namespace
CefExtensionsRendererClient::CefExtensionsRendererClient() {
}
@@ -24,4 +125,127 @@ int CefExtensionsRendererClient::GetLowestIsolatedWorldId() const {
return 1;
}
void CefExtensionsRendererClient::RenderThreadStarted() {
content::RenderThread* thread = content::RenderThread::Get();
extension_dispatcher_delegate_.reset(
new extensions::CefExtensionsDispatcherDelegate());
extension_dispatcher_.reset(
new extensions::Dispatcher(extension_dispatcher_delegate_.get()));
resource_request_policy_.reset(
new extensions::ResourceRequestPolicy(extension_dispatcher_.get()));
guest_view_container_dispatcher_.reset(
new extensions::ExtensionsGuestViewContainerDispatcher());
thread->AddObserver(extension_dispatcher_.get());
thread->AddObserver(guest_view_container_dispatcher_.get());
}
void CefExtensionsRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new extensions::ExtensionFrameHelper(render_frame,
extension_dispatcher_.get());
extension_dispatcher_->OnRenderFrameCreated(render_frame);
}
void CefExtensionsRendererClient::RenderViewCreated(
content::RenderView* render_view) {
new extensions::ExtensionHelper(render_view, extension_dispatcher_.get());
}
bool CefExtensionsRendererClient::OverrideCreatePlugin(
content::RenderFrame* render_frame,
const blink::WebPluginParams& params) {
if (params.mimeType.utf8() != content::kBrowserPluginMimeType)
return true;
bool guest_view_api_available = false;
extension_dispatcher_->script_context_set().ForEach(
render_frame, base::Bind(&IsGuestViewApiAvailableToScriptContext,
&guest_view_api_available));
return !guest_view_api_available;
}
bool CefExtensionsRendererClient::WillSendRequest(
blink::WebFrame* frame,
ui::PageTransition transition_type,
const GURL& url,
GURL* new_url) {
// Check whether the request should be allowed. If not allowed, we reset the
// URL to something invalid to prevent the request and cause an error.
if (url.SchemeIs(extensions::kExtensionScheme) &&
!resource_request_policy_->CanRequestResource(url, frame,
transition_type)) {
*new_url = GURL(chrome::kExtensionInvalidRequestURL);
return true;
}
if (url.SchemeIs(extensions::kExtensionResourceScheme) &&
!resource_request_policy_->CanRequestExtensionResourceScheme(url,
frame)) {
*new_url = GURL(chrome::kExtensionResourceInvalidRequestURL);
return true;
}
return false;
}
// static
bool CefExtensionsRendererClient::ShouldFork(blink::WebLocalFrame* frame,
const GURL& url,
bool is_initial_navigation,
bool is_server_redirect,
bool* send_referrer) {
const extensions::RendererExtensionRegistry* extension_registry =
extensions::RendererExtensionRegistry::Get();
// Determine if the new URL is an extension (excluding bookmark apps).
const extensions::Extension* new_url_extension =
extensions::GetNonBookmarkAppExtension(
*extension_registry->GetMainThreadExtensionSet(), url);
bool is_extension_url = !!new_url_extension;
// If the navigation would cross an app extent boundary, we also need
// to defer to the browser to ensure process isolation. This is not
// necessary for server redirects, which will be transferred to a new
// process by the browser process when they are ready to commit. It is
// necessary for client redirects, which won't be transferred in the same
// way.
if (!is_server_redirect &&
CrossesExtensionExtents(frame, url, is_extension_url,
is_initial_navigation)) {
// Include the referrer in this case since we're going from a hosted web
// page. (the packaged case is handled previously by the extension
// navigation test)
*send_referrer = true;
return true;
}
// If this is a reload, check whether it has the wrong process type. We
// should send it to the browser if it's an extension URL (e.g., hosted app)
// in a normal process, or if it's a process for an extension that has been
// uninstalled. Without --site-per-process mode, we never fork processes
// for subframes, so this check only makes sense for top-level frames.
// TODO(alexmos,nasko): Figure out how this check should work when reloading
// subframes in --site-per-process mode.
if (!frame->parent() && frame->document().url() == url) {
if (is_extension_url != IsStandaloneExtensionProcess())
return true;
}
return false;
}
// static
content::BrowserPluginDelegate*
CefExtensionsRendererClient::CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) {
if (mime_type == content::kBrowserPluginMimeType)
return new extensions::ExtensionsGuestViewContainer(render_frame);
return new extensions::MimeHandlerViewContainer(render_frame, mime_type,
original_url);
}
} // namespace extensions

View File

@@ -5,11 +5,34 @@
#ifndef CEF_LIBCEF_RENDERER_EXTENSIONS_EXTENSIONS_RENDERER_CLIENT_H_
#define CEF_LIBCEF_RENDERER_EXTENSIONS_EXTENSIONS_RENDERER_CLIENT_H_
#include <string>
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "extensions/renderer/extensions_renderer_client.h"
#include "ui/base/page_transition_types.h"
class GURL;
namespace blink {
class WebFrame;
class WebLocalFrame;
struct WebPluginParams;
}
namespace content {
class BrowserPluginDelegate;
class RenderFrame;
class RenderView;
}
namespace extensions {
class Dispatcher;
class DispatcherDelegate;
class ExtensionsGuestViewContainerDispatcher;
class ResourceRequestPolicy;
class CefExtensionsRendererClient : public ExtensionsRendererClient {
public:
CefExtensionsRendererClient();
@@ -19,7 +42,34 @@ class CefExtensionsRendererClient : public ExtensionsRendererClient {
bool IsIncognitoProcess() const override;
int GetLowestIsolatedWorldId() const override;
// See CefContentRendererClient methods with the same names.
void RenderThreadStarted();
void RenderFrameCreated(content::RenderFrame* render_frame);
void RenderViewCreated(content::RenderView* render_view);
bool OverrideCreatePlugin(content::RenderFrame* render_frame,
const blink::WebPluginParams& params);
bool WillSendRequest(blink::WebFrame* frame,
ui::PageTransition transition_type,
const GURL& url,
GURL* new_url);
static bool ShouldFork(blink::WebLocalFrame* frame,
const GURL& url,
bool is_initial_navigation,
bool is_server_redirect,
bool* send_referrer);
static content::BrowserPluginDelegate* CreateBrowserPluginDelegate(
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url);
private:
scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_;
scoped_ptr<extensions::Dispatcher> extension_dispatcher_;
scoped_ptr<extensions::ExtensionsGuestViewContainerDispatcher>
guest_view_container_dispatcher_;
scoped_ptr<extensions::ResourceRequestPolicy> resource_request_policy_;
DISALLOW_COPY_AND_ASSIGN(CefExtensionsRendererClient);
};

View File

@@ -8,12 +8,14 @@
#include "libcef/renderer/content_renderer_client.h"
#include "libcef/renderer/plugins/plugin_preroller.h"
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/renderer/custom_menu_commands.h"
#include "components/content_settings/content/common/content_settings_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
@@ -274,15 +276,24 @@ blink::WebPlugin* CefPluginPlaceholder::CreatePlugin() {
gin::ObjectTemplateBuilder CefPluginPlaceholder::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<CefPluginPlaceholder>::GetObjectTemplateBuilder(
isolate)
.SetMethod<void (CefPluginPlaceholder::*)()>(
"hide", &CefPluginPlaceholder::HideCallback)
.SetMethod<void (CefPluginPlaceholder::*)()>(
"load", &CefPluginPlaceholder::LoadCallback)
.SetMethod<void (CefPluginPlaceholder::*)()>(
"didFinishLoading",
&CefPluginPlaceholder::DidFinishLoadingCallback)
.SetMethod("openAboutPlugins",
&CefPluginPlaceholder::OpenAboutPluginsCallback);
gin::ObjectTemplateBuilder builder =
gin::Wrappable<CefPluginPlaceholder>::GetObjectTemplateBuilder(isolate)
.SetMethod<void (CefPluginPlaceholder::*)()>(
"hide", &CefPluginPlaceholder::HideCallback)
.SetMethod<void (CefPluginPlaceholder::*)()>(
"load", &CefPluginPlaceholder::LoadCallback)
.SetMethod<void (CefPluginPlaceholder::*)()>(
"didFinishLoading",
&CefPluginPlaceholder::DidFinishLoadingCallback)
.SetMethod("openAboutPlugins",
&CefPluginPlaceholder::OpenAboutPluginsCallback);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePluginPlaceholderTesting)) {
builder.SetMethod<void (CefPluginPlaceholder::*)()>(
"didFinishIconRepositionForTesting",
&CefPluginPlaceholder::DidFinishIconRepositionForTestingCallback);
}
return builder;
}

View File

@@ -34,7 +34,7 @@ class CefWebURLLoaderClient : public blink::WebURLLoaderClient {
~CefWebURLLoaderClient() override;
// blink::WebURLLoaderClient methods.
void willSendRequest(
void willFollowRedirect(
WebURLLoader* loader,
WebURLRequest& newRequest,
const WebURLResponse& redirectResponse) override;
@@ -260,7 +260,7 @@ CefWebURLLoaderClient::CefWebURLLoaderClient(
CefWebURLLoaderClient::~CefWebURLLoaderClient() {
}
void CefWebURLLoaderClient::willSendRequest(
void CefWebURLLoaderClient::willFollowRedirect(
WebURLLoader* loader,
WebURLRequest& newRequest,
const WebURLResponse& redirectResponse) {

View File

@@ -160,17 +160,22 @@ blink::WebFrame* FindFrameByUniqueName(const blink::WebString& unique_name,
return NULL;
}
bool ParseCSSColor(const blink::WebString& string, bool strict, SkColor& color) {
blink::RGBA32 rgba_color =
void InitializePartitionAlloc() {
WTF::Partitions::initialize(nullptr);
}
bool ParseCSSColor(const blink::WebString& string,
bool strict, SkColor& color) {
blink::Color rgba_color =
blink::makeRGBA(SkColorGetR(color), SkColorGetG(color),
SkColorGetB(color), SkColorGetA(color));
if (!blink::CSSParser::parseColor(rgba_color, string, strict))
return false;
color = SkColorSetARGB(blink::alphaChannel(rgba_color),
blink::redChannel(rgba_color),
blink::greenChannel(rgba_color),
blink::blueChannel(rgba_color));
color = SkColorSetARGB(rgba_color.alpha(),
rgba_color.red(),
rgba_color.green(),
rgba_color.blue());
return true;
}

View File

@@ -44,6 +44,10 @@ int64 GetIdentifier(blink::WebFrame* frame);
blink::WebFrame* FindFrameByUniqueName(const blink::WebString& unique_name,
blink::WebFrame* relative_to_frame);
// Initialize PartitionAlloc before calling Blink functions from the browser
// process. Safe to call multiple times.
void InitializePartitionAlloc();
bool ParseCSSColor(const blink::WebString& string, bool strict, SkColor& color);
} // webkit_glue