Introduce the use of Chromium types (issue #1336).

Changes to the CEF public API:
- Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types.
- Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask.
- Change CefRefPtr to extend scoped_refptr.
-- Change CefBase method signatures to match RefCountedThreadSafeBase.
- Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*.
-- Remove the CefAtomic* functions.
-- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro.
- Change IMPLEMENT_LOCKING to use base::Lock.
-- Remove the CefCriticalSection class.
-- Deprecate the IMPLEMENT_LOCKING macro.
-- base::Lock will DCHECK() in Debug builds if lock usage is reentrant.
- Move include/internal/cef_tuple.h to include/base/cef_tuple.h.
- Allow an empty |callback| parameter passed to CefBeginTracing.

Changes to the CEF implementation:
- Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro.
- Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations.
- Remove use of the IMPLEMENT_LOCKING macro.

Changes to cef_unittests:
- Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types.
- Fix wrong header include ordering.
- Remove use of the IMPLEMENT_LOCKING macro.

Changes to cefclient and cefsimple:
- Use base::Bind and cef_closure_task.h instead of NewCefRunnable*.
- Remove use of the IMPEMENT_LOCKING macro.
- Fix incorrect/unnecessary locking.
- Add additional runtime thread checks.
- Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2014-07-14 22:18:51 +00:00
parent c260a2d166
commit 122397acfc
314 changed files with 13077 additions and 1242 deletions

View File

@@ -10,13 +10,14 @@
#include <string>
#include <vector>
#include "include/base/cef_bind.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_path_util.h"
#include "include/cef_process_util.h"
#include "include/cef_runnable.h"
#include "include/cef_trace.h"
#include "include/cef_url.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "cefclient/binding_test.h"
#include "cefclient/cefclient.h"
@@ -89,9 +90,9 @@ bool ParseTestUrl(const std::string& url,
int ClientHandler::browser_count_ = 0;
ClientHandler::ClientHandler()
: main_handle_(NULL),
browser_id_(0),
: browser_id_(0),
is_closing_(false),
main_handle_(NULL),
edit_handle_(NULL),
back_handle_(NULL),
forward_handle_(NULL),
@@ -122,6 +123,8 @@ bool ClientHandler::OnProcessMessageReceived(
CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) {
CEF_REQUIRE_UI_THREAD();
if (message_router_->OnProcessMessageReceived(browser, source_process,
message)) {
return true;
@@ -146,6 +149,8 @@ void ClientHandler::OnBeforeContextMenu(
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model) {
CEF_REQUIRE_UI_THREAD();
if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) {
// Add a separator if the menu already has items.
if (model->GetCount() > 0)
@@ -166,6 +171,8 @@ bool ClientHandler::OnContextMenuCommand(
CefRefPtr<CefContextMenuParams> params,
int command_id,
EventFlags event_flags) {
CEF_REQUIRE_UI_THREAD();
switch (command_id) {
case CLIENT_ID_SHOW_DEVTOOLS:
ShowDevTools(browser);
@@ -186,6 +193,8 @@ bool ClientHandler::OnFileDialog(CefRefPtr<CefBrowser> browser,
const CefString& default_file_name,
const std::vector<CefString>& accept_types,
CefRefPtr<CefFileDialogCallback> callback) {
CEF_REQUIRE_UI_THREAD();
return false;
}
@@ -201,8 +210,6 @@ bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
std::string logFile;
{
AutoLock lock_scope(this);
first_message = log_file_.empty();
if (first_message) {
std::stringstream ss;
@@ -240,6 +247,7 @@ void ClientHandler::OnBeforeDownload(
const CefString& suggested_name,
CefRefPtr<CefBeforeDownloadCallback> callback) {
CEF_REQUIRE_UI_THREAD();
// Continue the download and show the "Save As" dialog.
callback->Continue(GetDownloadPath(suggested_name), true);
}
@@ -249,6 +257,7 @@ void ClientHandler::OnDownloadUpdated(
CefRefPtr<CefDownloadItem> download_item,
CefRefPtr<CefDownloadItemCallback> callback) {
CEF_REQUIRE_UI_THREAD();
if (download_item->IsComplete()) {
SetLastDownloadFile(download_item->GetFullPath());
SendNotification(NOTIFY_DOWNLOAD_COMPLETE);
@@ -272,6 +281,8 @@ bool ClientHandler::OnRequestGeolocationPermission(
const CefString& requesting_url,
int request_id,
CefRefPtr<CefGeolocationCallback> callback) {
CEF_REQUIRE_UI_THREAD();
// Allow geolocation access from all websites.
callback->Continue(true);
return true;
@@ -287,6 +298,7 @@ bool ClientHandler::OnJSDialog(CefRefPtr<CefBrowser> browser,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) {
CEF_REQUIRE_UI_THREAD();
return false;
}
@@ -295,10 +307,12 @@ bool ClientHandler::OnBeforeUnloadDialog(
const CefString& message_text,
bool is_reload,
CefRefPtr<CefJSDialogCallback> callback) {
CEF_REQUIRE_UI_THREAD();
return false;
}
void ClientHandler::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
}
#endif // !defined(OS_LINUX)
@@ -307,6 +321,8 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
const CefKeyEvent& event,
CefEventHandle os_event,
bool* is_keyboard_shortcut) {
CEF_REQUIRE_UI_THREAD();
if (!event.focus_on_editable_field && event.windows_key_code == 0x20) {
// Special handling for the space character when an input element does not
// have focus. Handling the event in OnPreKeyEvent() keeps the event from
@@ -332,6 +348,8 @@ bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings,
bool* no_javascript_access) {
CEF_REQUIRE_IO_THREAD();
if (browser->GetHost()->IsWindowRenderingDisabled()) {
// Cancel popups in off-screen rendering mode.
return true;
@@ -358,8 +376,8 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
if (mouse_cursor_change_disabled_)
browser->GetHost()->SetMouseCursorChangeDisabled(true);
AutoLock lock_scope(this);
if (!browser_.get()) {
if (!GetBrowser()) {
base::AutoLock lock_scope(lock_);
// We need to keep the main child window, but not popup windows
browser_ = browser;
browser_id_ = browser->GetIdentifier();
@@ -370,8 +388,7 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
// Give focus to the popup browser. Perform asynchronously because the
// parent window may attempt to keep focus after launching the popup.
CefPostTask(TID_UI,
NewCefRunnableMethod(browser->GetHost().get(),
&CefBrowserHost::SetFocus, true));
base::Bind(&CefBrowserHost::SetFocus, browser->GetHost().get(), true));
}
browser_count_++;
@@ -383,7 +400,8 @@ bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
// Closing the main window requires special handling. See the DoClose()
// documentation in the CEF header for a detailed destription of this
// process.
if (browser_id_ == browser->GetIdentifier()) {
if (GetBrowserId() == browser->GetIdentifier()) {
base::AutoLock lock_scope(lock_);
// Set a flag to indicate that the window close should be allowed.
is_closing_ = true;
}
@@ -398,9 +416,12 @@ void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
message_router_->OnBeforeClose(browser);
if (browser_id_ == browser->GetIdentifier()) {
// Free the browser pointer so that the browser can be destroyed
browser_ = NULL;
if (GetBrowserId() == browser->GetIdentifier()) {
{
base::AutoLock lock_scope(lock_);
// Free the browser pointer so that the browser can be destroyed
browser_ = NULL;
}
if (osr_handler_.get()) {
osr_handler_->OnBeforeClose(browser);
@@ -481,6 +502,8 @@ bool ClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_redirect) {
CEF_REQUIRE_UI_THREAD();
message_router_->OnBeforeBrowse(browser, frame);
return false;
}
@@ -489,6 +512,8 @@ CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
CEF_REQUIRE_IO_THREAD();
std::string url = request->GetURL();
if (url.find(kTestOrigin) == 0) {
// Handle URLs in the test origin.
@@ -523,6 +548,8 @@ bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
int64 new_size,
CefRefPtr<CefQuotaCallback> callback) {
CEF_REQUIRE_IO_THREAD();
static const int64 max_size = 1024 * 1024 * 20; // 20mb.
// Grant the quota request if the size is reasonable.
@@ -533,6 +560,8 @@ bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution) {
CEF_REQUIRE_UI_THREAD();
std::string urlStr = url;
// Allow OS execution of Spotify URIs.
@@ -542,6 +571,8 @@ void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) {
CEF_REQUIRE_UI_THREAD();
message_router_->OnRenderProcessTerminated(browser);
// Load the startup URL if that's not the website that we terminated on.
@@ -557,13 +588,15 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
}
bool ClientHandler::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
CefRect& rect) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetRootScreenRect(browser, rect);
}
bool ClientHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetViewRect(browser, rect);
@@ -574,6 +607,7 @@ bool ClientHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewY,
int& screenX,
int& screenY) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetScreenPoint(browser, viewX, viewY, screenX, screenY);
@@ -581,6 +615,7 @@ bool ClientHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
bool ClientHandler::GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetScreenInfo(browser, screen_info);
@@ -588,6 +623,7 @@ bool ClientHandler::GetScreenInfo(CefRefPtr<CefBrowser> browser,
void ClientHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
return osr_handler_->OnPopupShow(browser, show);
@@ -595,6 +631,7 @@ void ClientHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
void ClientHandler::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
return osr_handler_->OnPopupSize(browser, rect);
@@ -606,6 +643,7 @@ void ClientHandler::OnPaint(CefRefPtr<CefBrowser> browser,
const void* buffer,
int width,
int height) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
osr_handler_->OnPaint(browser, type, dirtyRects, buffer, width, height);
@@ -613,6 +651,7 @@ void ClientHandler::OnPaint(CefRefPtr<CefBrowser> browser,
void ClientHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
osr_handler_->OnCursorChange(browser, cursor);
@@ -622,6 +661,7 @@ bool ClientHandler::StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->StartDragging(browser, drag_data, allowed_ops, x, y);
@@ -629,38 +669,88 @@ bool ClientHandler::StartDragging(CefRefPtr<CefBrowser> browser,
void ClientHandler::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
osr_handler_->UpdateDragCursor(browser, operation);
}
void ClientHandler::SetMainWindowHandle(ClientWindowHandle handle) {
AutoLock lock_scope(this);
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetMainWindowHandle, this, handle));
return;
}
main_handle_ = handle;
}
ClientWindowHandle ClientHandler::GetMainWindowHandle() const {
CEF_REQUIRE_UI_THREAD();
return main_handle_;
}
void ClientHandler::SetEditWindowHandle(ClientWindowHandle handle) {
AutoLock lock_scope(this);
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetEditWindowHandle, this, handle));
return;
}
edit_handle_ = handle;
}
void ClientHandler::SetButtonWindowHandles(ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle) {
AutoLock lock_scope(this);
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetButtonWindowHandles, this,
backHandle, forwardHandle, reloadHandle, stopHandle));
return;
}
back_handle_ = backHandle;
forward_handle_ = forwardHandle;
reload_handle_ = reloadHandle;
stop_handle_ = stopHandle;
}
void ClientHandler::SetOSRHandler(CefRefPtr<RenderHandler> handler) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetOSRHandler, this, handler));
return;
}
osr_handler_ = handler;
}
CefRefPtr<ClientHandler::RenderHandler> ClientHandler::GetOSRHandler() const {
CEF_REQUIRE_UI_THREAD();
return osr_handler_;
}
CefRefPtr<CefBrowser> ClientHandler::GetBrowser() const {
base::AutoLock lock_scope(lock_);
return browser_;
}
int ClientHandler::GetBrowserId() const {
base::AutoLock lock_scope(lock_);
return browser_id_;
}
void ClientHandler::CloseAllBrowsers(bool force_close) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &ClientHandler::CloseAllBrowsers,
force_close));
base::Bind(&ClientHandler::CloseAllBrowsers, this, force_close));
return;
}
@@ -677,18 +767,23 @@ void ClientHandler::CloseAllBrowsers(bool force_close) {
}
}
std::string ClientHandler::GetLogFile() {
AutoLock lock_scope(this);
bool ClientHandler::IsClosing() const {
base::AutoLock lock_scope(lock_);
return is_closing_;
}
std::string ClientHandler::GetLogFile() const {
CEF_REQUIRE_UI_THREAD();
return log_file_;
}
void ClientHandler::SetLastDownloadFile(const std::string& fileName) {
AutoLock lock_scope(this);
CEF_REQUIRE_UI_THREAD();
last_download_file_ = fileName;
}
std::string ClientHandler::GetLastDownloadFile() {
AutoLock lock_scope(this);
std::string ClientHandler::GetLastDownloadFile() const {
CEF_REQUIRE_UI_THREAD();
return last_download_file_;
}
@@ -707,66 +802,74 @@ void ClientHandler::CloseDevTools(CefRefPtr<CefBrowser> browser) {
browser->GetHost()->CloseDevTools();
}
std::string ClientHandler::GetStartupURL() const {
return startup_url_;
}
void ClientHandler::BeginTracing() {
if (CefCurrentlyOn(TID_UI)) {
CefBeginTracing(CefString(), NULL);
} else {
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &ClientHandler::BeginTracing));
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI, base::Bind(&ClientHandler::BeginTracing, this));
return;
}
CefBeginTracing(CefString(), NULL);
}
void ClientHandler::EndTracing() {
if (CefCurrentlyOn(TID_UI)) {
class Client : public CefEndTracingCallback,
public CefRunFileDialogCallback {
public:
explicit Client(CefRefPtr<ClientHandler> handler)
: handler_(handler) {
RunDialog();
}
void RunDialog() {
static const char kDefaultFileName[] = "trace.txt";
std::string path = handler_->GetDownloadPath(kDefaultFileName);
if (path.empty())
path = kDefaultFileName;
// Results in a call to OnFileDialogDismissed.
handler_->GetBrowser()->GetHost()->RunFileDialog(
FILE_DIALOG_SAVE, CefString(), path, std::vector<CefString>(),
this);
}
virtual void OnFileDialogDismissed(
CefRefPtr<CefBrowserHost> browser_host,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!file_paths.empty()) {
// File selected. Results in a call to OnEndTracingComplete.
CefEndTracing(file_paths.front(), this);
} else {
// No file selected. Discard the trace data.
CefEndTracing(CefString(), NULL);
}
}
virtual void OnEndTracingComplete(
const CefString& tracing_file) OVERRIDE {
handler_->SetLastDownloadFile(tracing_file.ToString());
handler_->SendNotification(NOTIFY_DOWNLOAD_COMPLETE);
}
private:
CefRefPtr<ClientHandler> handler_;
IMPLEMENT_REFCOUNTING(Callback);
};
new Client(this);
} else {
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &ClientHandler::EndTracing));
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI, base::Bind(&ClientHandler::EndTracing, this));
return;
}
class Client : public CefEndTracingCallback,
public CefRunFileDialogCallback {
public:
explicit Client(CefRefPtr<ClientHandler> handler)
: handler_(handler) {
RunDialog();
}
void RunDialog() {
static const char kDefaultFileName[] = "trace.txt";
std::string path = handler_->GetDownloadPath(kDefaultFileName);
if (path.empty())
path = kDefaultFileName;
// Results in a call to OnFileDialogDismissed.
handler_->GetBrowser()->GetHost()->RunFileDialog(
FILE_DIALOG_SAVE, CefString(), path, std::vector<CefString>(),
this);
}
virtual void OnFileDialogDismissed(
CefRefPtr<CefBrowserHost> browser_host,
const std::vector<CefString>& file_paths) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
if (!file_paths.empty()) {
// File selected. Results in a call to OnEndTracingComplete.
CefEndTracing(file_paths.front(), this);
} else {
// No file selected. Discard the trace data.
CefEndTracing(CefString(), NULL);
}
}
virtual void OnEndTracingComplete(
const CefString& tracing_file) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
handler_->SetLastDownloadFile(tracing_file.ToString());
handler_->SendNotification(NOTIFY_DOWNLOAD_COMPLETE);
}
private:
CefRefPtr<ClientHandler> handler_;
IMPLEMENT_REFCOUNTING(Client);
};
new Client(this);
}
bool ClientHandler::Save(const std::string& path, const std::string& data) {