cef/libcef/browser/browser_info_manager.h
Marshall Greenblatt 4fbd247231 Add chrome runtime support for more callbacks and ceftests (see issue #2969)
This change adds support for:
- Protocol and request handling.
- Loading and navigation events.
- Display and focus events.
- Mouse/keyboard events.
- Popup browsers.
- Callbacks in the renderer process.
- Misc. functionality required for ceftests.

This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes
callback for configuring global state that will be applied to all
CefCookieManagers by default. This global callback is currently required by the
chrome runtime because the primary ProfileImpl is created via
ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before
OnContextCreated can be called.

ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default"
directory by default (on Windows). Cookies may persist in this directory when
running ceftests and may need to be manually deleted if those tests fail.

Remaining work includes:
- Support for client-created request contexts.
- Embedding the browser in a Views hierarchy (cefclient support).
- TryCloseBrowser and DoClose support.
- Most of the CefSettings configuration.
- DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod).
- CEF-specific WebUI pages (about, license, webui-hosts).
- Context menu customization (CefContextMenuHandler).
- Auto resize (SetAutoResizeEnabled).
- Zoom settings (SetZoomLevel).
- File dialog runner (RunFileDialog).
- File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler).
- Extension loading (LoadExtension, etc).
- Plugin loading (OnBeforePluginLoad).
- Widevine loading (CefRegisterWidevineCdm).
- PDF and print preview does not display.
- Crash reporting is untested.
- Mac: Web content loads but does not display.

The following ceftests are now passing when run with the
"--enable-chrome-runtime" command-line flag:

CorsTest.*
DisplayTest.*:-DisplayTest.AutoResize
DOMTest.*
DraggableRegionsTest.*
ImageTest.*
MessageRouterTest.*
NavigationTest.*
ParserTest.*
RequestContextTest.*Global*
RequestTest.*
ResourceManagerTest.*
ResourceRequestHandlerTest.*
ResponseTest.*
SchemeHandlerTest.*
ServerTest.*
StreamResourceHandlerTest.*
StreamTest.*
StringTest.*
TaskTest.*
TestServerTest.*
ThreadTest.*
URLRequestTest.*Global*
V8Test.*:-V8Test.OnUncaughtExceptionDevTools
ValuesTest.*
WaitableEventTest.*
XmlReaderTest.*
ZipReaderTest.*
2020-09-29 18:31:43 -04:00

247 lines
9.8 KiB
C++

// 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_BROWSER_INFO_MANAGER_H_
#define CEF_LIBCEF_BROWSER_BROWSER_INFO_MANAGER_H_
#pragma once
#include "include/cef_client.h"
#include <map>
#include <memory>
#include <vector>
#include "libcef/browser/browser_info.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/render_process_host_observer.h"
#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"
namespace blink {
struct WebWindowFeatures;
}
namespace content {
struct OpenURLParams;
struct Referrer;
class RenderFrameHost;
class RenderViewHostDelegateView;
class WebContents;
class WebContentsView;
} // namespace content
namespace IPC {
class Message;
}
class CefBrowserHostBase;
class CefBrowserPlatformDelegate;
// Singleton object for managing BrowserInfo instances.
class CefBrowserInfoManager : public content::RenderProcessHostObserver {
public:
CefBrowserInfoManager();
~CefBrowserInfoManager() override;
// Returns this singleton instance of this class.
static CefBrowserInfoManager* GetInstance();
// Called immediately before a new CefBrowserHost implementation is created
// directly. In this case |is_popup| will be true only for DevTools browsers.
scoped_refptr<CefBrowserInfo> CreateBrowserInfo(
bool is_popup,
bool is_windowless,
CefRefPtr<CefDictionaryValue> extra_info);
// Called from WebContentsDelegate::WebContentsCreated when a new browser is
// being created for a traditional popup (e.g. window.open() or targeted
// link). If any OnGetNewBrowserInfo requests are pending for the popup the
// response will be sent when this method is called.
scoped_refptr<CefBrowserInfo> CreatePopupBrowserInfo(
content::WebContents* new_contents,
bool is_windowless,
CefRefPtr<CefDictionaryValue> extra_info);
// Called from ContentBrowserClient::CanCreateWindow. See comments on
// PendingPopup for more information.
bool CanCreateWindow(content::RenderFrameHost* opener,
const GURL& target_url,
const content::Referrer& referrer,
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access);
// Called from WebContentsDelegate::GetCustomWebContentsView (alloy runtime
// only). See comments on PendingPopup for more information.
void GetCustomWebContentsView(
const GURL& target_url,
int opener_render_process_id,
int opener_render_routing_id,
content::WebContentsView** view,
content::RenderViewHostDelegateView** delegate_view);
// Called from WebContentsDelegate::WebContentsCreated. See comments on
// PendingPopup for more information.
void WebContentsCreated(
const GURL& target_url,
int opener_render_process_id,
int opener_render_routing_id,
CefBrowserSettings& settings,
CefRefPtr<CefClient>& client,
std::unique_ptr<CefBrowserPlatformDelegate>& platform_delegate,
CefRefPtr<CefDictionaryValue>& extra_info);
// Called from CefBrowserMessageFilter::OnGetNewBrowserInfo for delivering
// browser info to the renderer process. If the browser info already exists
// the response will be sent immediately. Otherwise, the response will be sent
// when CreatePopupBrowserInfo creates the browser info. The info will already
// exist for explicitly created browsers and guest views. It may sometimes
// already exist for traditional popup browsers depending on timing. See
// comments on PendingPopup for more information.
void OnGetNewBrowserInfo(int render_process_id,
int render_routing_id,
IPC::Message* reply_msg);
// Called from CefBrowserHostBase::DestroyBrowser() when a browser is
// destroyed.
void RemoveBrowserInfo(scoped_refptr<CefBrowserInfo> browser_info);
// Called from CefContext::FinishShutdownOnUIThread() to destroy all browsers.
void DestroyAllBrowsers();
// Returns the CefBrowserInfo matching the specified IDs or nullptr if no
// match is found. It is allowed to add new callers of this method but
// consider using CefBrowserHostBase::GetBrowserForFrameRoute() or
// extensions::GetOwnerBrowserForFrameRoute() instead. If |is_guest_view| is
// non-nullptr it will be set to true if the IDs match a guest view associated
// with the returned browser info instead of the browser itself.
scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrameRoute(
int render_process_id,
int render_routing_id,
bool* is_guest_view = nullptr);
// Returns the CefBrowserInfo matching the specified ID or nullptr if no match
// is found. It is allowed to add new callers of this method but consider
// using CefBrowserHostBase::GetBrowserForFrameTreeNode() instead. If
// |is_guest_view| is non-nullptr it will be set to true if the IDs match a
// guest view associated with the returned browser info instead of the browser
// itself.
scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrameTreeNode(
int frame_tree_node_id,
bool* is_guest_view = nullptr);
// Returns all existing CefBrowserInfo objects.
typedef std::list<scoped_refptr<CefBrowserInfo>> BrowserInfoList;
BrowserInfoList GetBrowserInfoList();
// Returns true if the navigation should be allowed to proceed, or false if
// the navigation will instead be sent via OpenURLFromTab. If allowed,
// |browser| will be set to the target browser if any.
bool MaybeAllowNavigation(content::RenderFrameHost* opener,
const content::OpenURLParams& params,
CefRefPtr<CefBrowserHostBase>& browser) const;
private:
// RenderProcessHostObserver methods:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
// Store state information about pending popups. Call order is:
// - CanCreateWindow (UIT):
// Provides an opportunity to cancel the popup (calls OnBeforePopup) and
// creates the new platform delegate for the popup. If the popup owner is
// an extension guest view then the popup is canceled and
// WebContentsDelegate::OpenURLFromTab is called via the
// CefBrowserHostBase::MaybeAllowNavigation implementation.
// And then the following calls may occur at the same time:
// - GetCustomWebContentsView (UIT) (alloy runtime only):
// Creates the OSR views for windowless popups.
// - WebContentsCreated (UIT):
// Creates the CefBrowserHost representation for the popup.
// - CefBrowserMessageFilter::OnGetNewBrowserInfo (IOT)
// Passes information about the popup to the renderer process.
struct PendingPopup {
// Track the last method that modified this PendingPopup instance. There may
// be multiple pending popups with the same identifiers and this allows us
// to differentiate between them at different processing steps.
enum Step {
CAN_CREATE_WINDOW,
GET_CUSTOM_WEB_CONTENTS_VIEW,
} step;
// Initial state from ViewHostMsg_CreateWindow.
// |target_url| will be empty if a popup is created via window.open() and
// never navigated. For example: javascript:window.open();
int opener_render_process_id;
int opener_render_routing_id;
GURL target_url;
std::string target_frame_name;
// Values specified by OnBeforePopup.
CefBrowserSettings settings;
CefRefPtr<CefClient> client;
CefRefPtr<CefDictionaryValue> extra_info;
// Platform delegate specific to the new popup.
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate;
};
// Manage pending popups. Only called on the UI thread.
void PushPendingPopup(std::unique_ptr<PendingPopup> popup);
std::unique_ptr<PendingPopup> PopPendingPopup(PendingPopup::Step step,
int opener_process_id,
int opener_routing_id,
const GURL& target_url);
// Retrieves the BrowserInfo matching the specified IDs. If both sets are
// valid then this method makes sure both sets have been registered.
scoped_refptr<CefBrowserInfo> GetBrowserInfo(int render_process_id,
int render_routing_id,
bool* is_guest_view);
// Send the response for a pending OnGetNewBrowserInfo request.
static void SendNewBrowserInfoResponse(
int render_process_id,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_guest_view,
IPC::Message* reply_msg);
// Time out a response if it's still pending.
static void TimeoutNewBrowserInfoResponse(int64_t frame_id, int timeout_id);
// Pending request for OnGetNewBrowserInfo.
struct PendingNewBrowserInfo {
int render_process_id;
int render_routing_id;
int timeout_id;
IPC::Message* reply_msg;
};
mutable base::Lock browser_info_lock_;
// Access to the below members must be protected by |browser_info_lock_|.
BrowserInfoList browser_info_list_;
int next_browser_id_ = 0;
// Map of frame ID to info.
using PendingNewBrowserInfoMap =
std::map<int64_t, std::unique_ptr<PendingNewBrowserInfo>>;
PendingNewBrowserInfoMap pending_new_browser_info_map_;
// Only accessed on the UI thread.
using PendingPopupList = std::vector<std::unique_ptr<PendingPopup>>;
PendingPopupList pending_popup_list_;
int next_timeout_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(CefBrowserInfoManager);
};
#endif // CEF_LIBCEF_BROWSER_BROWSER_INFO_H_