Introduce cef_runnable.h and cef_tuple.h and perform further thread-related cleanup (issue #175).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@176 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
942fa69d8b
commit
83dd15925f
5
cef.gyp
5
cef.gyp
|
@ -25,6 +25,11 @@
|
|||
'..',
|
||||
],
|
||||
'sources': [
|
||||
'include/cef.h',
|
||||
'include/cef_nplugin.h',
|
||||
'include/cef_runnable.h',
|
||||
'include/cef_tuple.h',
|
||||
'include/cef_wrapper.h',
|
||||
'tests/cefclient/binding_test.cpp',
|
||||
'tests/cefclient/binding_test.h',
|
||||
'tests/cefclient/cefclient.cpp',
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
// Copyright (c) 2011 Marshall A. Greenblatt. Portions Copyright (c)
|
||||
// 2006-2011 Google Inc. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||
// Framework nor the names of its contributors may be used to endorse
|
||||
// or promote products derived from this software without specific prior
|
||||
// written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// The contents of this file are a modified extract of base/task.h
|
||||
|
||||
#ifndef _CEF_RUNNABLE_H
|
||||
#define _CEF_RUNNABLE_H
|
||||
#pragma once
|
||||
|
||||
#include "cef.h"
|
||||
#ifdef BUILDING_CEF_SHARED
|
||||
#include "base/tuple.h"
|
||||
#else
|
||||
#include "cef_tuple.h"
|
||||
#endif
|
||||
|
||||
// CefRunnableMethodTraits -----------------------------------------------------
|
||||
//
|
||||
// This traits-class is used by CefRunnableMethod to manage the lifetime of the
|
||||
// callee object. By default, it is assumed that the callee supports AddRef
|
||||
// and Release methods. A particular class can specialize this template to
|
||||
// define other lifetime management. For example, if the callee is known to
|
||||
// live longer than the CefRunnableMethod object, then a CefRunnableMethodTraits
|
||||
// struct could be defined with empty RetainCallee and ReleaseCallee methods.
|
||||
//
|
||||
// The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way
|
||||
// for declaring a CefRunnableMethodTraits that disables refcounting.
|
||||
|
||||
template <class T>
|
||||
struct CefRunnableMethodTraits {
|
||||
CefRunnableMethodTraits() {
|
||||
}
|
||||
|
||||
~CefRunnableMethodTraits() {
|
||||
}
|
||||
|
||||
void RetainCallee(T* obj) {
|
||||
#ifndef NDEBUG
|
||||
// Catch NewCefRunnableMethod being called in an object's constructor.
|
||||
// This isn't safe since the method can be invoked before the constructor
|
||||
// completes, causing the object to be deleted.
|
||||
obj->AddRef();
|
||||
obj->Release();
|
||||
#endif
|
||||
obj->AddRef();
|
||||
}
|
||||
|
||||
void ReleaseCallee(T* obj) {
|
||||
obj->Release();
|
||||
}
|
||||
};
|
||||
|
||||
// Convenience macro for declaring a CefRunnableMethodTraits that disables
|
||||
// refcounting of a class. This is useful if you know that the callee
|
||||
// will outlive the CefRunnableMethod object and thus do not need the ref
|
||||
// counts.
|
||||
//
|
||||
// The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the
|
||||
// global namespace scope. Example:
|
||||
//
|
||||
// namespace foo {
|
||||
// class Bar {
|
||||
// ...
|
||||
// };
|
||||
// } // namespace foo
|
||||
//
|
||||
// DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar);
|
||||
//
|
||||
// This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the
|
||||
// class.
|
||||
#define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \
|
||||
template <> \
|
||||
struct CefRunnableMethodTraits<TypeName> { \
|
||||
void RetainCallee(TypeName* manager) {} \
|
||||
void ReleaseCallee(TypeName* manager) {} \
|
||||
}
|
||||
|
||||
// CefRunnableMethod and CefRunnableFunction ----------------------------------
|
||||
//
|
||||
// CefRunnable methods are a type of task that call a function on an object
|
||||
// when they are run. We implement both an object and a set of
|
||||
// NewCefRunnableMethod and NewCefRunnableFunction functions for convenience.
|
||||
// These functions are overloaded and will infer the template types,
|
||||
// simplifying calling code.
|
||||
//
|
||||
// The template definitions all use the following names:
|
||||
// T - the class type of the object you're supplying
|
||||
// this is not needed for the Static version of the call
|
||||
// Method/Function - the signature of a pointer to the method or function you
|
||||
// want to call
|
||||
// Param - the parameter(s) to the method, possibly packed as a Tuple
|
||||
// A - the first parameter (if any) to the method
|
||||
// B - the second parameter (if any) to the method
|
||||
//
|
||||
// Put these all together and you get an object that can call a method whose
|
||||
// signature is:
|
||||
// R T::MyFunction([A[, B]])
|
||||
//
|
||||
// Usage:
|
||||
// CefPostTask(TID_UI, NewCefRunnableMethod(object, &Object::method[, a[, b]])
|
||||
// CefPostTask(TID_UI, NewCefRunnableFunction(&function[, a[, b]])
|
||||
|
||||
// CefRunnableMethod and NewCefRunnableMethod implementation ------------------
|
||||
|
||||
template <class T, class Method, class Params>
|
||||
class CefRunnableMethod : public CefThreadSafeBase<CefTask> {
|
||||
public:
|
||||
CefRunnableMethod(T* obj, Method meth, const Params& params)
|
||||
: obj_(obj), meth_(meth), params_(params) {
|
||||
traits_.RetainCallee(obj_);
|
||||
}
|
||||
|
||||
~CefRunnableMethod() {
|
||||
T* obj = obj_;
|
||||
obj_ = NULL;
|
||||
if (obj)
|
||||
traits_.ReleaseCallee(obj);
|
||||
}
|
||||
|
||||
virtual void Execute(CefThreadId threadId) {
|
||||
if (obj_)
|
||||
DispatchToMethod(obj_, meth_, params_);
|
||||
}
|
||||
|
||||
private:
|
||||
T* obj_;
|
||||
Method meth_;
|
||||
Params params_;
|
||||
CefRunnableMethodTraits<T> traits_;
|
||||
};
|
||||
|
||||
template <class T, class Method>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method) {
|
||||
return new CefRunnableMethod<T, Method, Tuple0>(object, method, MakeTuple());
|
||||
}
|
||||
|
||||
template <class T, class Method, class A>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a) {
|
||||
return new CefRunnableMethod<T, Method, Tuple1<A> >(object,
|
||||
method,
|
||||
MakeTuple(a));
|
||||
}
|
||||
|
||||
template <class T, class Method, class A, class B>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a, const B& b) {
|
||||
return new CefRunnableMethod<T, Method, Tuple2<A, B> >(object, method,
|
||||
MakeTuple(a, b));
|
||||
}
|
||||
|
||||
template <class T, class Method, class A, class B, class C>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a, const B& b,
|
||||
const C& c) {
|
||||
return new CefRunnableMethod<T, Method, Tuple3<A, B, C> >(object, method,
|
||||
MakeTuple(a, b,
|
||||
c));
|
||||
}
|
||||
|
||||
template <class T, class Method, class A, class B, class C, class D>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d) {
|
||||
return new CefRunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method,
|
||||
MakeTuple(a, b,
|
||||
c,
|
||||
d));
|
||||
}
|
||||
|
||||
template <class T, class Method, class A, class B, class C, class D, class E>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e) {
|
||||
return new CefRunnableMethod<T,
|
||||
Method,
|
||||
Tuple5<A, B, C, D, E> >(object,
|
||||
method,
|
||||
MakeTuple(a, b, c, d,
|
||||
e));
|
||||
}
|
||||
|
||||
template <class T, class Method, class A, class B, class C, class D, class E,
|
||||
class F>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e, const F& f) {
|
||||
return new CefRunnableMethod<T,
|
||||
Method,
|
||||
Tuple6<A, B, C, D, E, F> >(object,
|
||||
method,
|
||||
MakeTuple(a, b, c, d,
|
||||
e, f));
|
||||
}
|
||||
|
||||
template <class T, class Method, class A, class B, class C, class D, class E,
|
||||
class F, class G>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableMethod(T* object, Method method,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e, const F& f,
|
||||
const G& g) {
|
||||
return new CefRunnableMethod<T,
|
||||
Method,
|
||||
Tuple7<A, B, C, D, E, F, G> >(object,
|
||||
method,
|
||||
MakeTuple(a, b, c,
|
||||
d, e, f,
|
||||
g));
|
||||
}
|
||||
|
||||
// CefRunnableFunction and NewCefRunnableFunction implementation --------------
|
||||
|
||||
template <class Function, class Params>
|
||||
class CefRunnableFunction : public CefThreadSafeBase<CefTask> {
|
||||
public:
|
||||
CefRunnableFunction(Function function, const Params& params)
|
||||
: function_(function), params_(params) {
|
||||
}
|
||||
|
||||
~CefRunnableFunction() {
|
||||
}
|
||||
|
||||
virtual void Execute(CefThreadId threadId) {
|
||||
if (function_)
|
||||
DispatchToFunction(function_, params_);
|
||||
}
|
||||
|
||||
private:
|
||||
Function function_;
|
||||
Params params_;
|
||||
};
|
||||
|
||||
template <class Function>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function) {
|
||||
return new CefRunnableFunction<Function, Tuple0>(function, MakeTuple());
|
||||
}
|
||||
|
||||
template <class Function, class A>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a) {
|
||||
return new CefRunnableFunction<Function, Tuple1<A> >(function, MakeTuple(a));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b) {
|
||||
return new CefRunnableFunction<Function, Tuple2<A, B> >(function,
|
||||
MakeTuple(a, b));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B, class C>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b,
|
||||
const C& c) {
|
||||
return new CefRunnableFunction<Function, Tuple3<A, B, C> >(function,
|
||||
MakeTuple(a, b,
|
||||
c));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B, class C, class D>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d) {
|
||||
return new CefRunnableFunction<Function, Tuple4<A, B, C, D> >(function,
|
||||
MakeTuple(a, b,
|
||||
c,
|
||||
d));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B, class C, class D, class E>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e) {
|
||||
return new CefRunnableFunction<Function, Tuple5<A, B, C, D, E> >(function,
|
||||
MakeTuple(a, b, c, d, e));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B, class C, class D, class E,
|
||||
class F>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e, const F& f) {
|
||||
return new CefRunnableFunction<Function, Tuple6<A, B, C, D, E, F> >(function,
|
||||
MakeTuple(a, b, c, d, e, f));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B, class C, class D, class E,
|
||||
class F, class G>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e, const F& f,
|
||||
const G& g) {
|
||||
return new CefRunnableFunction<Function, Tuple7<A, B, C, D, E, F, G> >(
|
||||
function, MakeTuple(a, b, c, d, e, f, g));
|
||||
}
|
||||
|
||||
template <class Function, class A, class B, class C, class D, class E,
|
||||
class F, class G, class H>
|
||||
inline CefRefPtr<CefTask> NewCefRunnableFunction(Function function,
|
||||
const A& a, const B& b,
|
||||
const C& c, const D& d,
|
||||
const E& e, const F& f,
|
||||
const G& g, const H& h) {
|
||||
return new CefRunnableFunction<Function, Tuple8<A, B, C, D, E, F, G, H> >(
|
||||
function, MakeTuple(a, b, c, d, e, f, g, h));
|
||||
}
|
||||
|
||||
#endif // _CEF_RUNNABLE_H
|
File diff suppressed because it is too large
Load Diff
|
@ -278,66 +278,57 @@ void CefBrowserImpl::CloseDevTools()
|
|||
|
||||
void CefBrowserImpl::Undo(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_UNDO, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_UNDO, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::Redo(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_REDO, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_REDO, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::Cut(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_CUT, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_CUT, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::Copy(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_COPY, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_COPY, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::Paste(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_PASTE, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_PASTE, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::Delete(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_DELETE, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_DELETE, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::SelectAll(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_SELECTALL, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_SELECTALL, frame));
|
||||
}
|
||||
|
||||
|
||||
void CefBrowserImpl::Print(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_PRINT, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_PRINT, frame));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::ViewSource(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_VIEWSOURCE, frame.get()));
|
||||
&CefBrowserImpl::UIT_HandleAction, MENU_ID_VIEWSOURCE, frame));
|
||||
}
|
||||
|
||||
CefString CefBrowserImpl::GetSource(CefRefPtr<CefFrame> frame)
|
||||
|
@ -374,27 +365,23 @@ void CefBrowserImpl::LoadRequest(CefRefPtr<CefFrame> frame,
|
|||
CefRefPtr<CefRequest> request)
|
||||
{
|
||||
DCHECK(request.get() != NULL);
|
||||
frame->AddRef();
|
||||
request->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_LoadURLForRequestRef, frame.get(), request.get()));
|
||||
&CefBrowserImpl::UIT_LoadURLForRequestRef, frame, request));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::LoadURL(CefRefPtr<CefFrame> frame,
|
||||
const CefString& url)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_LoadURL, frame.get(), url));
|
||||
&CefBrowserImpl::UIT_LoadURL, frame, url));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::LoadString(CefRefPtr<CefFrame> frame,
|
||||
const CefString& string,
|
||||
const CefString& url)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_LoadHTML, frame.get(), string, url));
|
||||
&CefBrowserImpl::UIT_LoadHTML, frame, string, url));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::LoadStream(CefRefPtr<CefFrame> frame,
|
||||
|
@ -402,11 +389,8 @@ void CefBrowserImpl::LoadStream(CefRefPtr<CefFrame> frame,
|
|||
const CefString& url)
|
||||
{
|
||||
DCHECK(stream.get() != NULL);
|
||||
frame->AddRef();
|
||||
stream->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_LoadHTMLForStreamRef, frame.get(), stream.get(),
|
||||
url));
|
||||
&CefBrowserImpl::UIT_LoadHTMLForStreamRef, frame, stream, url));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::ExecuteJavaScript(CefRefPtr<CefFrame> frame,
|
||||
|
@ -414,9 +398,8 @@ void CefBrowserImpl::ExecuteJavaScript(CefRefPtr<CefFrame> frame,
|
|||
const CefString& scriptUrl,
|
||||
int startLine)
|
||||
{
|
||||
frame->AddRef();
|
||||
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this,
|
||||
&CefBrowserImpl::UIT_ExecuteJavaScript, frame.get(), jsCode, scriptUrl,
|
||||
&CefBrowserImpl::UIT_ExecuteJavaScript, frame, jsCode, scriptUrl,
|
||||
startLine));
|
||||
}
|
||||
|
||||
|
@ -532,11 +515,23 @@ void CefBrowserImpl::UIT_DestroyBrowser()
|
|||
handler_->HandleBeforeWindowClose(this);
|
||||
}
|
||||
UIT_GetWebViewDelegate()->RevokeDragDrop();
|
||||
|
||||
// If the current browser window is a dev tools client then disconnect from
|
||||
// the agent and destroy the client before destroying the window.
|
||||
UIT_DestroyDevToolsClient();
|
||||
|
||||
if (dev_tools_agent_.get()) {
|
||||
BrowserDevToolsClient* client = dev_tools_agent_->client();
|
||||
if (client)
|
||||
client->browser()->UIT_DestroyBrowser();
|
||||
if (client) {
|
||||
// Destroy the client before freeing the agent.
|
||||
client->browser()->UIT_DestroyDevToolsClient();
|
||||
if(!_Context->shutting_down()) {
|
||||
// Explicitly close the client browser window.
|
||||
client->browser()->UIT_CloseBrowser();
|
||||
}
|
||||
}
|
||||
// Free the agent.
|
||||
dev_tools_agent_.reset();
|
||||
}
|
||||
|
||||
// Clean up anything associated with the WebViewHost widget.
|
||||
|
@ -550,20 +545,20 @@ void CefBrowserImpl::UIT_DestroyBrowser()
|
|||
_Context->RemoveBrowser(this);
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_LoadURL(CefFrame* frame,
|
||||
void CefBrowserImpl::UIT_LoadURL(CefRefPtr<CefFrame> frame,
|
||||
const CefString& url)
|
||||
{
|
||||
UIT_LoadURLForRequest(frame, url, CefString(), WebHTTPBody(),
|
||||
CefRequest::HeaderMap());
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_LoadURLForRequestRef(CefFrame* frame,
|
||||
CefRequest* request)
|
||||
void CefBrowserImpl::UIT_LoadURLForRequestRef(CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request)
|
||||
{
|
||||
CefString url = request->GetURL();
|
||||
CefString method = request->GetMethod();
|
||||
|
||||
CefRequestImpl *impl = static_cast<CefRequestImpl*>(request);
|
||||
CefRequestImpl *impl = static_cast<CefRequestImpl*>(request.get());
|
||||
|
||||
WebHTTPBody upload_data;
|
||||
CefRefPtr<CefPostData> postdata = impl->GetPostData();
|
||||
|
@ -576,11 +571,9 @@ void CefBrowserImpl::UIT_LoadURLForRequestRef(CefFrame* frame,
|
|||
impl->GetHeaderMap(headers);
|
||||
|
||||
UIT_LoadURLForRequest(frame, url, method, upload_data, headers);
|
||||
|
||||
request->Release();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_LoadURLForRequest(CefFrame* frame,
|
||||
void CefBrowserImpl::UIT_LoadURLForRequest(CefRefPtr<CefFrame> frame,
|
||||
const CefString& url,
|
||||
const CefString& method,
|
||||
const WebKit::WebHTTPBody& upload_data,
|
||||
|
@ -605,11 +598,9 @@ void CefBrowserImpl::UIT_LoadURLForRequest(CefFrame* frame,
|
|||
nav_controller_->LoadEntry(
|
||||
new BrowserNavigationEntry(-1, gurl, CefString(), frame->GetName(),
|
||||
method, upload_data, headers));
|
||||
|
||||
frame->Release();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_LoadHTML(CefFrame* frame,
|
||||
void CefBrowserImpl::UIT_LoadHTML(CefRefPtr<CefFrame> frame,
|
||||
const CefString& html,
|
||||
const CefString& url)
|
||||
{
|
||||
|
@ -629,12 +620,10 @@ void CefBrowserImpl::UIT_LoadHTML(CefFrame* frame,
|
|||
WebFrame* web_frame = UIT_GetWebFrame(frame);
|
||||
if(web_frame)
|
||||
web_frame->loadHTMLString(std::string(html), gurl);
|
||||
|
||||
frame->Release();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_LoadHTMLForStreamRef(CefFrame* frame,
|
||||
CefStreamReader* stream,
|
||||
void CefBrowserImpl::UIT_LoadHTMLForStreamRef(CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefStreamReader> stream,
|
||||
const CefString& url)
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
@ -666,12 +655,9 @@ void CefBrowserImpl::UIT_LoadHTMLForStreamRef(CefFrame* frame,
|
|||
WebFrame* web_frame = UIT_GetWebFrame(frame);
|
||||
if(web_frame)
|
||||
web_frame->loadHTMLString(ss.str(), gurl);
|
||||
|
||||
stream->Release();
|
||||
frame->Release();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_ExecuteJavaScript(CefFrame* frame,
|
||||
void CefBrowserImpl::UIT_ExecuteJavaScript(CefRefPtr<CefFrame> frame,
|
||||
const CefString& js_code,
|
||||
const CefString& script_url,
|
||||
int start_line)
|
||||
|
@ -683,8 +669,6 @@ void CefBrowserImpl::UIT_ExecuteJavaScript(CefFrame* frame,
|
|||
web_frame->executeScript(WebScriptSource(string16(js_code),
|
||||
WebURL(GURL(std::string(script_url))), start_line));
|
||||
}
|
||||
|
||||
frame->Release();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_GoBackOrForward(int offset)
|
||||
|
@ -826,7 +810,7 @@ void CefBrowserImpl::UIT_HandleActionView(CefHandler::MenuId menuId)
|
|||
}
|
||||
|
||||
void CefBrowserImpl::UIT_HandleAction(CefHandler::MenuId menuId,
|
||||
CefFrame* frame)
|
||||
CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
||||
|
@ -889,9 +873,6 @@ void CefBrowserImpl::UIT_HandleAction(CefHandler::MenuId menuId,
|
|||
UIT_ViewDocumentString(web_frame);
|
||||
break;
|
||||
}
|
||||
|
||||
if(frame)
|
||||
frame->Release();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_Find(int identifier, const CefString& search_text,
|
||||
|
@ -1094,6 +1075,18 @@ void CefBrowserImpl::UIT_ShowDevTools()
|
|||
}
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseDevTools()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
||||
if(!dev_tools_agent_.get())
|
||||
return;
|
||||
|
||||
BrowserDevToolsClient* client = dev_tools_agent_->client();
|
||||
if (client)
|
||||
client->browser()->UIT_CloseBrowser();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::set_zoom_level(double zoomLevel)
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
|
@ -1130,6 +1123,15 @@ void CefBrowserImpl::UIT_CreateDevToolsClient(BrowserDevToolsAgent *agent)
|
|||
dev_tools_client_.reset(new BrowserDevToolsClient(this, agent));
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_DestroyDevToolsClient()
|
||||
{
|
||||
if (dev_tools_client_.get()) {
|
||||
// Free the client. This will cause the client to clear pending messages
|
||||
// and detach from the agent.
|
||||
dev_tools_client_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// CefFrameImpl
|
||||
|
||||
|
|
|
@ -180,25 +180,33 @@ public:
|
|||
title_ = title;
|
||||
}
|
||||
|
||||
// Create the native browser window and populate browser members.
|
||||
void UIT_CreateBrowser(const CefString& url);
|
||||
|
||||
// Destroy the browser members. This method should only be called after the
|
||||
// native browser window is not longer processing messages.
|
||||
void UIT_DestroyBrowser();
|
||||
|
||||
void UIT_LoadURL(CefFrame* frame,
|
||||
// Sends a message via the OS to close the native browser window.
|
||||
// UIT_DestroyBrowser will be called after the native window has closed.
|
||||
void UIT_CloseBrowser();
|
||||
|
||||
void UIT_LoadURL(CefRefPtr<CefFrame> frame,
|
||||
const CefString& url);
|
||||
void UIT_LoadURLForRequest(CefFrame* frame,
|
||||
void UIT_LoadURLForRequest(CefRefPtr<CefFrame> frame,
|
||||
const CefString& url,
|
||||
const CefString& method,
|
||||
const WebKit::WebHTTPBody& upload_data,
|
||||
const CefRequest::HeaderMap& headers);
|
||||
void UIT_LoadURLForRequestRef(CefFrame* frame,
|
||||
CefRequest* request);
|
||||
void UIT_LoadHTML(CefFrame* frame,
|
||||
void UIT_LoadURLForRequestRef(CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request);
|
||||
void UIT_LoadHTML(CefRefPtr<CefFrame> frame,
|
||||
const CefString& html,
|
||||
const CefString& url);
|
||||
void UIT_LoadHTMLForStreamRef(CefFrame* frame,
|
||||
CefStreamReader* stream,
|
||||
void UIT_LoadHTMLForStreamRef(CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefStreamReader> stream,
|
||||
const CefString& url);
|
||||
void UIT_ExecuteJavaScript(CefFrame* frame,
|
||||
void UIT_ExecuteJavaScript(CefRefPtr<CefFrame> frame,
|
||||
const CefString& js_code,
|
||||
const CefString& script_url,
|
||||
int start_line);
|
||||
|
@ -218,7 +226,7 @@ public:
|
|||
|
||||
// Handles most simple browser actions
|
||||
void UIT_HandleActionView(CefHandler::MenuId menuId);
|
||||
void UIT_HandleAction(CefHandler::MenuId menuId, CefFrame* frame);
|
||||
void UIT_HandleAction(CefHandler::MenuId menuId, CefRefPtr<CefFrame> frame);
|
||||
|
||||
// Save the document HTML to a temporary file and open in the default viewing
|
||||
// application
|
||||
|
@ -262,6 +270,7 @@ public:
|
|||
|
||||
protected:
|
||||
void UIT_CreateDevToolsClient(BrowserDevToolsAgent* agent);
|
||||
void UIT_DestroyDevToolsClient();
|
||||
|
||||
protected:
|
||||
CefWindowInfo window_info_;
|
||||
|
|
|
@ -66,11 +66,17 @@ void CefBrowserImpl::UIT_CreateBrowser(const CefString& url)
|
|||
handler_->HandleAfterCreated(this);
|
||||
}
|
||||
|
||||
if(url.size() > 0) {
|
||||
CefRefPtr<CefFrame> frame = GetMainFrame();
|
||||
frame->AddRef();
|
||||
UIT_LoadURL(frame, url);
|
||||
}
|
||||
if(url.size() > 0)
|
||||
UIT_LoadURL(GetMainFrame(), url);
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseBrowser()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
DCHECK(!_Context->shutting_down());
|
||||
|
||||
// TODO(port): Close the browser window.
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable)
|
||||
|
@ -136,14 +142,3 @@ int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
|
|||
NOTIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseDevTools()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
||||
if(!dev_tools_agent_.get())
|
||||
return;
|
||||
|
||||
// TODO(port): Add implementation.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
|
|
@ -71,11 +71,17 @@ void CefBrowserImpl::UIT_CreateBrowser(const CefString& url)
|
|||
handler_->HandleAfterCreated(this);
|
||||
}
|
||||
|
||||
if(url.size() > 0) {
|
||||
CefRefPtr<CefFrame> frame = GetMainFrame();
|
||||
frame->AddRef();
|
||||
UIT_LoadURL(frame, url);
|
||||
}
|
||||
if(url.size() > 0)
|
||||
UIT_LoadURL(GetMainFrame(), url);
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseBrowser()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
DCHECK(!_Context->shutting_down());
|
||||
|
||||
// TODO(port): Close the browser window.
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable)
|
||||
|
@ -145,14 +151,3 @@ int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
|
|||
NOTIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseDevTools()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
||||
if(!dev_tools_agent_.get())
|
||||
return;
|
||||
|
||||
// TODO(port): Add implementation.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
|
|
@ -149,11 +149,16 @@ void CefBrowserImpl::UIT_CreateBrowser(const CefString& url)
|
|||
handler_->HandleAfterCreated(this);
|
||||
}
|
||||
|
||||
if(url.length() > 0) {
|
||||
CefRefPtr<CefFrame> frame = GetMainFrame();
|
||||
frame->AddRef();
|
||||
UIT_LoadURL(frame, url);
|
||||
}
|
||||
if(url.length() > 0)
|
||||
UIT_LoadURL(GetMainFrame(), url);
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseBrowser()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
DCHECK(!_Context->shutting_down());
|
||||
|
||||
PostMessage(UIT_GetMainWndHandle(), WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable)
|
||||
|
@ -489,15 +494,3 @@ int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
|
|||
|
||||
return page_count;
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_CloseDevTools()
|
||||
{
|
||||
REQUIRE_UIT();
|
||||
|
||||
if(!dev_tools_agent_.get())
|
||||
return;
|
||||
|
||||
BrowserDevToolsClient* client = dev_tools_agent_->client();
|
||||
if (client)
|
||||
PostMessage(client->browser()->UIT_GetMainWndHandle(), WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
|
|
@ -371,9 +371,7 @@ void BrowserWebViewDelegate::showContextMenu(
|
|||
|
||||
if(!handled) {
|
||||
// Execute the action
|
||||
CefRefPtr<CefFrame> frame = browser_->GetFocusedFrame();
|
||||
frame->AddRef();
|
||||
browser_->UIT_HandleAction(menuId, frame.get());
|
||||
browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,13 +154,15 @@ bool CefCurrentlyOn(CefThreadId threadId)
|
|||
return CefThread::CurrentlyOn(static_cast<CefThread::ID>(id));
|
||||
}
|
||||
|
||||
class CefTaskHelper : public base::RefCountedThreadSafe<CefTaskHelper>
|
||||
class CefTaskHelper : public Task
|
||||
{
|
||||
public:
|
||||
CefTaskHelper(CefRefPtr<CefTask> task) : task_(task) {}
|
||||
void Execute(CefThreadId threadId) { task_->Execute(threadId); }
|
||||
CefTaskHelper(CefRefPtr<CefTask> task, CefThreadId threadId)
|
||||
: task_(task), thread_id_(threadId) {}
|
||||
virtual void Run() { task_->Execute(thread_id_); }
|
||||
private:
|
||||
CefRefPtr<CefTask> task_;
|
||||
CefThreadId thread_id_;
|
||||
DISALLOW_COPY_AND_ASSIGN(CefTaskHelper);
|
||||
};
|
||||
|
||||
|
@ -170,9 +172,8 @@ bool CefPostTask(CefThreadId threadId, CefRefPtr<CefTask> task)
|
|||
if(id < 0)
|
||||
return false;
|
||||
|
||||
scoped_refptr<CefTaskHelper> helper(new CefTaskHelper(task));
|
||||
return CefThread::PostTask(static_cast<CefThread::ID>(id), FROM_HERE,
|
||||
NewRunnableMethod(helper.get(), &CefTaskHelper::Execute, threadId));
|
||||
new CefTaskHelper(task, threadId));
|
||||
}
|
||||
|
||||
bool CefPostDelayedTask(CefThreadId threadId, CefRefPtr<CefTask> task,
|
||||
|
@ -182,10 +183,8 @@ bool CefPostDelayedTask(CefThreadId threadId, CefRefPtr<CefTask> task,
|
|||
if(id < 0)
|
||||
return false;
|
||||
|
||||
scoped_refptr<CefTaskHelper> helper(new CefTaskHelper(task));
|
||||
return CefThread::PostDelayedTask(static_cast<CefThread::ID>(id), FROM_HERE,
|
||||
NewRunnableMethod(helper.get(), &CefTaskHelper::Execute, threadId),
|
||||
delay_ms);
|
||||
new CefTaskHelper(task, threadId), delay_ms);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// can be found in the LICENSE file.
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "include/cef_runnable.h"
|
||||
#include "include/cef_wrapper.h"
|
||||
#include "cefclient.h"
|
||||
#include "binding_test.h"
|
||||
|
@ -289,52 +290,41 @@ CefWindowHandle AppGetMainHwnd()
|
|||
return g_handler->GetMainHwnd();
|
||||
}
|
||||
|
||||
static void ExecuteGetSource(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
// Retrieve the current page source and display.
|
||||
std::string source = frame->GetSource();
|
||||
source = StringReplace(source, "<", "<");
|
||||
source = StringReplace(source, ">", ">");
|
||||
std::stringstream ss;
|
||||
ss << "<html><body>Source:" << "<pre>" << source
|
||||
<< "</pre></body></html>";
|
||||
frame->LoadString(ss.str(), "http://tests/getsource");
|
||||
}
|
||||
|
||||
void RunGetSourceTest(CefRefPtr<CefBrowser> browser)
|
||||
{
|
||||
// Execute the GetSource() call on the UI thread.
|
||||
class ExecTask : public CefThreadSafeBase<CefTask>
|
||||
{
|
||||
public:
|
||||
ExecTask(CefRefPtr<CefFrame> frame) : m_Frame(frame) {}
|
||||
virtual void Execute(CefThreadId threadId)
|
||||
{
|
||||
// Retrieve the current page source and display.
|
||||
std::string source = m_Frame->GetSource();
|
||||
source = StringReplace(source, "<", "<");
|
||||
source = StringReplace(source, ">", ">");
|
||||
std::stringstream ss;
|
||||
ss << "<html><body>Source:" << "<pre>" << source
|
||||
<< "</pre></body></html>";
|
||||
m_Frame->LoadString(ss.str(), "http://tests/getsource");
|
||||
}
|
||||
private:
|
||||
CefRefPtr<CefFrame> m_Frame;
|
||||
};
|
||||
CefPostTask(TID_UI, new ExecTask(browser->GetMainFrame()));
|
||||
CefPostTask(TID_UI,
|
||||
NewCefRunnableFunction(&ExecuteGetSource, browser->GetMainFrame()));
|
||||
}
|
||||
|
||||
static void ExecuteGetText(CefRefPtr<CefFrame> frame)
|
||||
{
|
||||
std::string text = frame->GetText();
|
||||
text = StringReplace(text, "<", "<");
|
||||
text = StringReplace(text, ">", ">");
|
||||
std::stringstream ss;
|
||||
ss << "<html><body>Text:" << "<pre>" << text
|
||||
<< "</pre></body></html>";
|
||||
frame->LoadString(ss.str(), "http://tests/gettext");
|
||||
}
|
||||
|
||||
void RunGetTextTest(CefRefPtr<CefBrowser> browser)
|
||||
{
|
||||
// Execute the GetText() call on the UI thread.
|
||||
class ExecTask : public CefThreadSafeBase<CefTask>
|
||||
{
|
||||
public:
|
||||
ExecTask(CefRefPtr<CefFrame> frame) : m_Frame(frame) {}
|
||||
virtual void Execute(CefThreadId threadId)
|
||||
{
|
||||
// Retrieve the current page text and display.
|
||||
std::string text = m_Frame->GetText();
|
||||
text = StringReplace(text, "<", "<");
|
||||
text = StringReplace(text, ">", ">");
|
||||
std::stringstream ss;
|
||||
ss << "<html><body>Text:" << "<pre>" << text
|
||||
<< "</pre></body></html>";
|
||||
m_Frame->LoadString(ss.str(), "http://tests/gettext");
|
||||
}
|
||||
private:
|
||||
CefRefPtr<CefFrame> m_Frame;
|
||||
};
|
||||
CefPostTask(TID_UI, new ExecTask(browser->GetMainFrame()));
|
||||
CefPostTask(TID_UI,
|
||||
NewCefRunnableFunction(&ExecuteGetText, browser->GetMainFrame()));
|
||||
}
|
||||
|
||||
void RunRequestTest(CefRefPtr<CefBrowser> browser)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "include/cef_runnable.h"
|
||||
#include "download_handler.h"
|
||||
#include "util.h"
|
||||
#include <sstream>
|
||||
|
@ -14,38 +15,6 @@
|
|||
#include <shlwapi.h>
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// Template for creating a task that executes a method with no arguments.
|
||||
template <class T, class Method>
|
||||
class Task : public CefThreadSafeBase<CefTask>
|
||||
{
|
||||
public:
|
||||
Task(T* object, Method method)
|
||||
: object_(object), method_(method) {}
|
||||
|
||||
virtual void Execute(CefThreadId threadId)
|
||||
{
|
||||
(object_->*method_)();
|
||||
}
|
||||
|
||||
protected:
|
||||
CefRefPtr<T> object_;
|
||||
Method method_;
|
||||
};
|
||||
|
||||
// Helper method for posting a task on a specific thread.
|
||||
template <class T, class Method>
|
||||
inline void PostOnThread(CefThreadId threadId,
|
||||
T* object,
|
||||
Method method) {
|
||||
CefRefPtr<CefTask> task = new Task<T,Method>(object, method);
|
||||
CefPostTask(threadId, task);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Implementation of the CefDownloadHandler interface.
|
||||
class ClientDownloadHandler : public CefThreadSafeBase<CefDownloadHandler>
|
||||
{
|
||||
|
@ -54,8 +23,6 @@ public:
|
|||
const CefString& fileName)
|
||||
: listener_(listener), filename_(fileName), file_(NULL)
|
||||
{
|
||||
// Open the file on the FILE thread.
|
||||
PostOnThread(TID_FILE, this, &ClientDownloadHandler::OnOpen);
|
||||
}
|
||||
|
||||
~ClientDownloadHandler()
|
||||
|
@ -72,15 +39,9 @@ public:
|
|||
|
||||
if(file_) {
|
||||
// Close the dangling file pointer on the FILE thread.
|
||||
class TaskCloseFile : public CefThreadSafeBase<CefTask>
|
||||
{
|
||||
public:
|
||||
TaskCloseFile(FILE* file) : file_(file) {}
|
||||
virtual void Execute(CefThreadId threadId) { fclose(file_); }
|
||||
private:
|
||||
FILE* file_;
|
||||
};
|
||||
CefPostTask(TID_FILE, new TaskCloseFile(file_));
|
||||
CefPostTask(TID_FILE,
|
||||
NewCefRunnableFunction(&ClientDownloadHandler::CloseDanglingFile,
|
||||
file_));
|
||||
|
||||
// Notify the listener that the download failed.
|
||||
listener_->NotifyDownloadError(filename_);
|
||||
|
@ -91,6 +52,13 @@ public:
|
|||
// The following methods are called on the UI thread.
|
||||
// --------------------------------------------------
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
// Open the file on the FILE thread.
|
||||
CefPostTask(TID_FILE,
|
||||
NewCefRunnableMethod(this, &ClientDownloadHandler::OnOpen));
|
||||
}
|
||||
|
||||
// A portion of the file contents have been received. This method will be
|
||||
// called multiple times until the download is complete. Return |true| to
|
||||
// continue receiving data and |false| to cancel.
|
||||
|
@ -111,7 +79,8 @@ public:
|
|||
Unlock();
|
||||
|
||||
// Write data to file on the FILE thread.
|
||||
PostOnThread(TID_FILE, this, &ClientDownloadHandler::OnReceivedData);
|
||||
CefPostTask(TID_FILE,
|
||||
NewCefRunnableMethod(this, &ClientDownloadHandler::OnReceivedData));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -121,7 +90,8 @@ public:
|
|||
REQUIRE_UI_THREAD();
|
||||
|
||||
// Flush and close the file on the FILE thread.
|
||||
PostOnThread(TID_FILE, this, &ClientDownloadHandler::OnComplete);
|
||||
CefPostTask(TID_FILE,
|
||||
NewCefRunnableMethod(this, &ClientDownloadHandler::OnComplete));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
@ -222,6 +192,11 @@ public:
|
|||
data.clear();
|
||||
}
|
||||
|
||||
static void CloseDanglingFile(FILE *file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<DownloadListener> listener_;
|
||||
CefString filename_;
|
||||
|
@ -232,5 +207,8 @@ private:
|
|||
CefRefPtr<CefDownloadHandler> CreateDownloadHandler(
|
||||
CefRefPtr<DownloadListener> listener, const CefString& fileName)
|
||||
{
|
||||
return new ClientDownloadHandler(listener, fileName);
|
||||
CefRefPtr<ClientDownloadHandler> handler =
|
||||
new ClientDownloadHandler(listener, fileName);
|
||||
handler->Initialize();
|
||||
return handler.get();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue