From 06ceab7447198560cf53e3133c7ec50134beac12 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Sat, 24 Jul 2010 16:49:42 +0000 Subject: [PATCH] - Use base::WaitableEvent for thread synchronization to eliminate Windows dependency. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@91 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- libcef/browser_impl.cc | 197 +++++++++++++++++++++++++++++ libcef/browser_impl.h | 16 +-- libcef/browser_impl_win.cc | 202 ------------------------------ libcef/browser_webkit_glue.cc | 17 --- libcef/browser_webkit_glue_win.cc | 17 +++ libcef/cef_context.h | 2 +- libcef/cef_thread.h | 2 +- 7 files changed, 225 insertions(+), 228 deletions(-) diff --git a/libcef/browser_impl.cc b/libcef/browser_impl.cc index 966d040fb..b51065c6a 100644 --- a/libcef/browser_impl.cc +++ b/libcef/browser_impl.cc @@ -7,8 +7,10 @@ #include "browser_impl.h" #include "browser_webkit_glue.h" #include "request_impl.h" +#include "stream_impl.h" #include "base/utf_string_conversions.h" +#include "base/waitable_event.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebHTTPBody.h" @@ -24,6 +26,7 @@ #include "webkit/glue/glue_serialize.h" #include "webkit/glue/plugins/webplugin_delegate.h" #include "webkit/glue/plugins/webplugin_impl.h" +#include "webkit/glue/webkit_glue.h" using WebKit::WebDocument; using WebKit::WebFrame; @@ -52,12 +55,69 @@ CefBrowserImpl::CefBrowserImpl(CefWindowInfo& windowInfo, bool popup, nav_controller_.reset(new BrowserNavigationController(this)); } + +bool CefBrowserImpl::CanGoBack() +{ + if(!CefThread::CurrentlyOn(CefThread::UI)) + { + // We need to send the request to the UI thread and wait for the result + + // Event that will be used to signal that data is available. Start + // in non-signaled mode so that the event will block. + base::WaitableEvent event(false, false); + + bool retVal = true; + + // Request the data from the UI thread + CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, + &CefBrowserImpl::UIT_CanGoBackNotify, &retVal, &event)); + + // Wait for the UI thread callback to tell us that the data is available + event.Wait(); + + return retVal; + } + else + { + // Call the method directly + return UIT_CanGoBack(); + } +} + void CefBrowserImpl::GoBack() { CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, &CefBrowserImpl::UIT_HandleActionView, MENU_ID_NAV_BACK)); } +bool CefBrowserImpl::CanGoForward() +{ + if(!CefThread::CurrentlyOn(CefThread::UI)) + { + // We need to send the request to the UI thread and wait for the result + + // Event that will be used to signal that data is available. Start + // in non-signaled mode so that the event will block. + base::WaitableEvent event(false, false); + + bool retVal = true; + + // Request the data from the UI thread + CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, + &CefBrowserImpl::UIT_CanGoForwardNotify, &retVal, &event)); + + // Wait for the UI thread callback to tell us that the data is available + event.Wait(); + + return retVal; + } + else + { + // Call the method directly + return UIT_CanGoForward(); + } +} + void CefBrowserImpl::GoForward() { CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, @@ -269,6 +329,78 @@ void CefBrowserImpl::ViewSource(CefRefPtr frame) &CefBrowserImpl::UIT_HandleAction, MENU_ID_VIEWSOURCE, frame.get())); } +std::wstring CefBrowserImpl::GetSource(CefRefPtr frame) +{ + if(!CefThread::CurrentlyOn(CefThread::UI)) + { + // We need to send the request to the UI thread and wait for the result + + // Event that will be used to signal that data is available. Start + // in non-signaled mode so that the event will block. + base::WaitableEvent event(false, false); + + CefRefPtr stream(new CefBytesWriter(BUFFER_SIZE)); + + // Request the data from the UI thread + frame->AddRef(); + stream->AddRef(); + CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, + &CefBrowserImpl::UIT_GetDocumentStringNotify, frame.get(), stream.get(), + &event)); + + // Wait for the UI thread callback to tell us that the data is available + event.Wait(); + + return UTF8ToWide( + static_cast(stream.get())->GetDataString()); + } + else + { + // Retrieve the document string directly + WebKit::WebFrame* web_frame = GetWebFrame(frame); + if(web_frame) { + std::string markup = web_frame->contentAsMarkup().utf8(); + return UTF8ToWide(markup); + } + return std::wstring(); + } +} + +std::wstring CefBrowserImpl::GetText(CefRefPtr frame) +{ + if(!CefThread::CurrentlyOn(CefThread::UI)) + { + // We need to send the request to the UI thread and wait for the result + + // Event that will be used to signal that data is available. Start + // in non-signaled mode so that the event will block. + base::WaitableEvent event(false, false); + + CefRefPtr stream(new CefBytesWriter(BUFFER_SIZE)); + + // Request the data from the UI thread + frame->AddRef(); + stream->AddRef(); + CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, + &CefBrowserImpl::UIT_GetDocumentTextNotify, frame.get(), stream.get(), + &event)); + + // Wait for the UI thread callback to tell us that the data is available + event.Wait(); + + return UTF8ToWide( + static_cast(stream.get())->GetDataString()); + } + else + { + // Retrieve the document text directly + WebKit::WebFrame* web_frame = GetWebFrame(frame); + if(web_frame) + return webkit_glue::DumpDocumentText(web_frame); + return std::wstring(); + } +} + void CefBrowserImpl::LoadRequest(CefRefPtr frame, CefRefPtr request) { @@ -707,6 +839,71 @@ void CefBrowserImpl::UIT_HandleAction(CefHandler::MenuId menuId, frame->Release(); } +void CefBrowserImpl::UIT_GetDocumentStringNotify(CefFrame* frame, + CefStreamWriter* writer, + base::WaitableEvent* event) +{ + REQUIRE_UIT(); + + WebKit::WebFrame* web_frame = GetWebFrame(frame); + if(web_frame) { + // Retrieve the document string + std::string markup = web_frame->contentAsMarkup().utf8(); + // Write the document string to the stream + writer->Write(markup.c_str(), markup.size(), 1); + } + + // Notify the calling thread that the data is now available + event->Signal(); + + writer->Release(); + frame->Release(); +} + +void CefBrowserImpl::UIT_GetDocumentTextNotify(CefFrame* frame, + CefStreamWriter* writer, + base::WaitableEvent* event) +{ + REQUIRE_UIT(); + + WebKit::WebFrame* web_frame = GetWebFrame(frame); + if(web_frame) { + // Retrieve the document string + std::wstring str = webkit_glue::DumpDocumentText(web_frame); + std::string cstr = WideToUTF8(str); + // Write the document string to the stream + writer->Write(cstr.c_str(), cstr.size(), 1); + } + + // Notify the calling thread that the data is now available + event->Signal(); + + writer->Release(); + frame->Release(); +} + +void CefBrowserImpl::UIT_CanGoBackNotify(bool *retVal, + base::WaitableEvent* event) +{ + REQUIRE_UIT(); + + *retVal = UIT_CanGoBack(); + + // Notify the calling thread that the data is now available + event->Signal(); +} + +void CefBrowserImpl::UIT_CanGoForwardNotify(bool *retVal, + base::WaitableEvent* event) +{ + REQUIRE_UIT(); + + *retVal = UIT_CanGoForward(); + + // Notify the calling thread that the data is now available + event->Signal(); +} + void CefBrowserImpl::UIT_Find(int identifier, const std::wstring& search_text, const WebKit::WebFindOptions& options) { diff --git a/libcef/browser_impl.h b/libcef/browser_impl.h index f68dbccbb..73ae76c3f 100644 --- a/libcef/browser_impl.h +++ b/libcef/browser_impl.h @@ -18,6 +18,9 @@ #include "third_party/WebKit/WebKit/chromium/public/WebFindOptions.h" +namespace base { +class WaitableEvent; +} namespace WebKit { class WebView; } @@ -196,14 +199,13 @@ public: // Save the document HTML to a temporary file and open in the default viewing // application bool UIT_ViewDocumentString(WebKit::WebFrame *frame); -#if defined(OS_WIN) void UIT_GetDocumentStringNotify(CefFrame* frame, - CefStreamWriter* writer, HANDLE hEvent); - void UIT_GetDocumentTextNotify(CefFrame* frame, - CefStreamWriter* writer, HANDLE hEvent); - void UIT_CanGoBackNotify(bool *retVal, HANDLE hEvent); - void UIT_CanGoForwardNotify(bool *retVal, HANDLE hEvent); -#endif + CefStreamWriter* writer, + base::WaitableEvent* event); + void UIT_GetDocumentTextNotify(CefFrame* frame, CefStreamWriter* writer, + base::WaitableEvent* event); + void UIT_CanGoBackNotify(bool *retVal, base::WaitableEvent* event); + void UIT_CanGoForwardNotify(bool *retVal, base::WaitableEvent* event); bool UIT_CanGoBack() { return !nav_controller_->IsAtStart(); } bool UIT_CanGoForward() { return !nav_controller_->IsAtEnd(); } diff --git a/libcef/browser_impl_win.cc b/libcef/browser_impl_win.cc index 89b4fd774..767b6875f 100644 --- a/libcef/browser_impl_win.cc +++ b/libcef/browser_impl_win.cc @@ -5,8 +5,6 @@ #include "cef_context.h" #include "browser_impl.h" -#include "browser_webkit_glue.h" -#include "stream_impl.h" #include "printing/units.h" #include "base/utf_string_conversions.h" @@ -16,7 +14,6 @@ #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" -#include "webkit/glue/webkit_glue.h" #include #include @@ -109,142 +106,6 @@ CefWindowHandle CefBrowserImpl::GetWindowHandle() return handle; } -std::wstring CefBrowserImpl::GetSource(CefRefPtr frame) -{ - if(!CefThread::CurrentlyOn(CefThread::UI)) - { - // We need to send the request to the UI thread and wait for the result - - // Event that will be used to signal that data is available. Start - // in non-signaled mode so that the event will block. - HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - DCHECK(hEvent != NULL); - - CefRefPtr stream(new CefBytesWriter(BUFFER_SIZE)); - - // Request the data from the UI thread - frame->AddRef(); - stream->AddRef(); - CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, - &CefBrowserImpl::UIT_GetDocumentStringNotify, frame.get(), stream.get(), - hEvent)); - - // Wait for the UI thread callback to tell us that the data is available - WaitForSingleObject(hEvent, INFINITE); - CloseHandle(hEvent); - - return UTF8ToWide( - static_cast(stream.get())->GetDataString()); - } - else - { - // Retrieve the document string directly - WebKit::WebFrame* web_frame = GetWebFrame(frame); - if(web_frame) { - std::string markup = web_frame->contentAsMarkup().utf8(); - return UTF8ToWide(markup); - } - return std::wstring(); - } -} - -std::wstring CefBrowserImpl::GetText(CefRefPtr frame) -{ - if(!CefThread::CurrentlyOn(CefThread::UI)) - { - // We need to send the request to the UI thread and wait for the result - - // Event that will be used to signal that data is available. Start - // in non-signaled mode so that the event will block. - HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - DCHECK(hEvent != NULL); - - CefRefPtr stream(new CefBytesWriter(BUFFER_SIZE)); - - // Request the data from the UI thread - frame->AddRef(); - stream->AddRef(); - CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, - &CefBrowserImpl::UIT_GetDocumentTextNotify, frame.get(), stream.get(), - hEvent)); - - // Wait for the UI thread callback to tell us that the data is available - WaitForSingleObject(hEvent, INFINITE); - CloseHandle(hEvent); - - return UTF8ToWide( - static_cast(stream.get())->GetDataString()); - } - else - { - // Retrieve the document text directly - WebKit::WebFrame* web_frame = GetWebFrame(frame); - if(web_frame) - return webkit_glue::DumpDocumentText(web_frame); - return std::wstring(); - } -} - -bool CefBrowserImpl::CanGoBack() -{ - if(!CefThread::CurrentlyOn(CefThread::UI)) - { - // We need to send the request to the UI thread and wait for the result - - // Event that will be used to signal that data is available. Start - // in non-signaled mode so that the event will block. - HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - DCHECK(hEvent != NULL); - - bool retVal = true; - - // Request the data from the UI thread - CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, - &CefBrowserImpl::UIT_CanGoBackNotify, &retVal, hEvent)); - - // Wait for the UI thread callback to tell us that the data is available - WaitForSingleObject(hEvent, INFINITE); - CloseHandle(hEvent); - - return retVal; - } - else - { - // Call the method directly - return UIT_CanGoBack(); - } -} - -bool CefBrowserImpl::CanGoForward() -{ - if(!CefThread::CurrentlyOn(CefThread::UI)) - { - // We need to send the request to the UI thread and wait for the result - - // Event that will be used to signal that data is available. Start - // in non-signaled mode so that the event will block. - HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - DCHECK(hEvent != NULL); - - bool retVal = true; - - // Request the data from the UI thread - CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, - &CefBrowserImpl::UIT_CanGoForwardNotify, &retVal, hEvent)); - - // Wait for the UI thread callback to tell us that the data is available - WaitForSingleObject(hEvent, INFINITE); - CloseHandle(hEvent); - - return retVal; - } - else - { - // Call the method directly - return UIT_CanGoForward(); - } -} - void CefBrowserImpl::UIT_CreateBrowser(const std::wstring& url) { REQUIRE_UIT(); @@ -367,69 +228,6 @@ bool CefBrowserImpl::UIT_ViewDocumentString(WebKit::WebFrame *frame) return true; } -void CefBrowserImpl::UIT_GetDocumentStringNotify(CefFrame* frame, - CefStreamWriter* writer, - HANDLE hEvent) -{ - REQUIRE_UIT(); - - WebKit::WebFrame* web_frame = GetWebFrame(frame); - if(web_frame) { - // Retrieve the document string - std::string markup = web_frame->contentAsMarkup().utf8(); - // Write the document string to the stream - writer->Write(markup.c_str(), markup.size(), 1); - } - - // Notify the calling thread that the data is now available - SetEvent(hEvent); - - writer->Release(); - frame->Release(); -} - -void CefBrowserImpl::UIT_GetDocumentTextNotify(CefFrame* frame, - CefStreamWriter* writer, - HANDLE hEvent) -{ - REQUIRE_UIT(); - - WebKit::WebFrame* web_frame = GetWebFrame(frame); - if(web_frame) { - // Retrieve the document string - std::wstring str = webkit_glue::DumpDocumentText(web_frame); - std::string cstr = WideToUTF8(str); - // Write the document string to the stream - writer->Write(cstr.c_str(), cstr.size(), 1); - } - - // Notify the calling thread that the data is now available - SetEvent(hEvent); - - writer->Release(); - frame->Release(); -} - -void CefBrowserImpl::UIT_CanGoBackNotify(bool *retVal, HANDLE hEvent) -{ - REQUIRE_UIT(); - - *retVal = UIT_CanGoBack(); - - // Notify the calling thread that the data is now available - SetEvent(hEvent); -} - -void CefBrowserImpl::UIT_CanGoForwardNotify(bool *retVal, HANDLE hEvent) -{ - REQUIRE_UIT(); - - *retVal = UIT_CanGoForward(); - - // Notify the calling thread that the data is now available - SetEvent(hEvent); -} - void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages, const gfx::Size& canvas_size, WebKit::WebFrame* frame) { diff --git a/libcef/browser_webkit_glue.cc b/libcef/browser_webkit_glue.cc index 2b0c2e27c..128c446d2 100644 --- a/libcef/browser_webkit_glue.cc +++ b/libcef/browser_webkit_glue.cc @@ -17,7 +17,6 @@ MSVC_POP_WARNING(); #undef LOG #include "base/logging.h" #include "base/path_service.h" -#include "base/resource_util.h" #include "base/scoped_ptr.h" #include "base/string16.h" #include "base/utf_string_conversions.h" @@ -44,22 +43,6 @@ void AppendToLog(const char* file, int line, const char* msg) { logging::LogMessage(file, line).stream() << msg; } -base::StringPiece GetRawDataResource(HMODULE module, int resource_id) { - void* data_ptr; - size_t data_size; - return base::GetDataResourceFromModule(module, resource_id, &data_ptr, - &data_size) - ? base::StringPiece(static_cast(data_ptr), data_size) - : base::StringPiece(); -} - -base::StringPiece NetResourceProvider(int key) { - HMODULE hModule = ::GetModuleHandle(L"libcef.dll"); - if(!hModule) - hModule = ::GetModuleHandle(NULL); - return GetRawDataResource(hModule, key); -} - base::StringPiece GetDataResource(int resource_id) { return NetResourceProvider(resource_id); } diff --git a/libcef/browser_webkit_glue_win.cc b/libcef/browser_webkit_glue_win.cc index d906c8438..8295a3ac5 100644 --- a/libcef/browser_webkit_glue_win.cc +++ b/libcef/browser_webkit_glue_win.cc @@ -18,6 +18,7 @@ MSVC_POP_WARNING(); #undef LOG #include "base/logging.h" +#include "base/resource_util.h" #include "gfx/gdi_util.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" @@ -49,6 +50,22 @@ HCURSOR LoadCursor(int cursor_id) { return NULL; } +base::StringPiece GetRawDataResource(HMODULE module, int resource_id) { + void* data_ptr; + size_t data_size; + return base::GetDataResourceFromModule(module, resource_id, &data_ptr, + &data_size) + ? base::StringPiece(static_cast(data_ptr), data_size) + : base::StringPiece(); +} + +base::StringPiece NetResourceProvider(int key) { + HMODULE hModule = ::GetModuleHandle(L"libcef.dll"); + if(!hModule) + hModule = ::GetModuleHandle(NULL); + return GetRawDataResource(hModule, key); +} + void GetPlugins(bool refresh, std::vector* plugins) { NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); } diff --git a/libcef/cef_context.h b/libcef/cef_context.h index eaf99aa9a..046f74109 100644 --- a/libcef/cef_context.h +++ b/libcef/cef_context.h @@ -78,4 +78,4 @@ private: // Global context object pointer extern CefRefPtr _Context; -#endif // _CONTEXT_H +#endif // _CEF_CONTEXT_H diff --git a/libcef/cef_thread.h b/libcef/cef_thread.h index ff655a4b1..eed4ff1ed 100644 --- a/libcef/cef_thread.h +++ b/libcef/cef_thread.h @@ -46,7 +46,7 @@ class CefThread : public base::Thread { // This is the thread that interacts with the file system. FILE, - // This is the thread that processes IPC and network messages. + // This is the thread that processes network and schema messages. IO, // This identifier does not represent a thread. Instead it counts the