This source file includes following definitions.
- dispatcher_
- DispatcherOwner
- RenderFrameDeleted
- GetExtensionWindowController
- GetAssociatedWebContents
- dispatcher
- render_frame_host
- Create
- dispatcher_owner_initialized_
- OverrideTaskRunnerForMessage
- OnResourceMessageReceived
- OnPost
- OnCall
- EnsureDispatcherOwnerInitialized
- DetachDispatcherOwner
- PopulateParams
- OnExtensionFunctionCompleted
- HandleRequest
#include "chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_messages.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/proxy/ppapi_messages.h"
namespace chrome {
class PepperExtensionsCommonMessageFilter::DispatcherOwner
: public content::WebContentsObserver,
public extensions::ExtensionFunctionDispatcher::Delegate {
public:
DispatcherOwner(PepperExtensionsCommonMessageFilter* message_filter,
Profile* profile,
content::RenderFrameHost* frame_host,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
render_frame_host_(frame_host),
message_filter_(message_filter),
dispatcher_(profile, this) {
}
virtual ~DispatcherOwner() {
message_filter_->DetachDispatcherOwner();
}
virtual void RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) OVERRIDE {
if (render_frame_host == render_frame_host_)
delete this;
}
virtual extensions::WindowController* GetExtensionWindowController(
) const OVERRIDE {
NOTREACHED();
return NULL;
}
virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE {
NOTREACHED();
return NULL;
}
extensions::ExtensionFunctionDispatcher* dispatcher() { return &dispatcher_; }
content::RenderFrameHost* render_frame_host() { return render_frame_host_; }
private:
content::RenderFrameHost* render_frame_host_;
scoped_refptr<PepperExtensionsCommonMessageFilter> message_filter_;
extensions::ExtensionFunctionDispatcher dispatcher_;
DISALLOW_COPY_AND_ASSIGN(DispatcherOwner);
};
PepperExtensionsCommonMessageFilter*
PepperExtensionsCommonMessageFilter::Create(content::BrowserPpapiHost* host,
PP_Instance instance) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
int render_process_id = 0;
int render_frame_id = 0;
if (!host->GetRenderFrameIDsForInstance(instance, &render_process_id,
&render_frame_id)) {
return NULL;
}
base::FilePath profile_directory = host->GetProfileDataDirectory();
GURL document_url = host->GetDocumentURLForInstance(instance);
return new PepperExtensionsCommonMessageFilter(render_process_id,
render_frame_id,
profile_directory,
document_url);
}
PepperExtensionsCommonMessageFilter::PepperExtensionsCommonMessageFilter(
int render_process_id,
int render_frame_id,
const base::FilePath& profile_directory,
const GURL& document_url)
: render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
profile_directory_(profile_directory),
document_url_(document_url),
dispatcher_owner_(NULL),
dispatcher_owner_initialized_(false) {
}
PepperExtensionsCommonMessageFilter::~PepperExtensionsCommonMessageFilter() {
}
scoped_refptr<base::TaskRunner>
PepperExtensionsCommonMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& msg) {
return content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::UI);
}
int32_t PepperExtensionsCommonMessageFilter::OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) {
IPC_BEGIN_MESSAGE_MAP(PepperExtensionsCommonMessageFilter, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_ExtensionsCommon_Post,
OnPost)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_ExtensionsCommon_Call,
OnCall)
IPC_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
int32_t PepperExtensionsCommonMessageFilter::OnPost(
ppapi::host::HostMessageContext* context,
const std::string& request_name,
base::ListValue& args) {
if (HandleRequest(context, request_name, &args, false))
return PP_OK;
else
return PP_ERROR_FAILED;
}
int32_t PepperExtensionsCommonMessageFilter::OnCall(
ppapi::host::HostMessageContext* context,
const std::string& request_name,
base::ListValue& args) {
if (HandleRequest(context, request_name, &args, true))
return PP_OK_COMPLETIONPENDING;
else
return PP_ERROR_FAILED;
}
void PepperExtensionsCommonMessageFilter::EnsureDispatcherOwnerInitialized() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (dispatcher_owner_initialized_)
return;
dispatcher_owner_initialized_ = true;
DCHECK(!dispatcher_owner_);
content::RenderFrameHost* frame_host = content::RenderFrameHost::FromID(
render_process_id_, render_frame_id_);
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(frame_host);
if (!document_url_.SchemeIs(extensions::kExtensionScheme))
return;
ProfileManager* profile_manager = g_browser_process->profile_manager();
if (!profile_manager)
return;
Profile* profile = profile_manager->GetProfile(profile_directory_);
dispatcher_owner_ = new DispatcherOwner(
this, profile, frame_host, web_contents);
}
void PepperExtensionsCommonMessageFilter::DetachDispatcherOwner() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
dispatcher_owner_ = NULL;
}
void PepperExtensionsCommonMessageFilter::PopulateParams(
const std::string& request_name,
base::ListValue* args,
bool has_callback,
ExtensionHostMsg_Request_Params* params) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
params->name = request_name;
params->arguments.Swap(args);
params->extension_id = document_url_.host();
params->source_url = document_url_;
params->request_id = 0;
params->has_callback = has_callback;
params->user_gesture = false;
}
void PepperExtensionsCommonMessageFilter::OnExtensionFunctionCompleted(
scoped_ptr<ppapi::host::ReplyMessageContext> reply_context,
ExtensionFunction::ResponseType type,
const base::ListValue& results,
const std::string& ) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (!reply_context) {
DCHECK_EQ(0u, results.GetSize());
return;
}
if (type == ExtensionFunction::BAD_MESSAGE) {
type = ExtensionFunction::FAILED;
}
reply_context->params.set_result(
type == ExtensionFunction::SUCCEEDED ? PP_OK : PP_ERROR_FAILED);
SendReply(*reply_context, PpapiPluginMsg_ExtensionsCommon_CallReply(results));
}
bool PepperExtensionsCommonMessageFilter::HandleRequest(
ppapi::host::HostMessageContext* context,
const std::string& request_name,
base::ListValue* args,
bool has_callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
EnsureDispatcherOwnerInitialized();
if (!dispatcher_owner_)
return false;
ExtensionHostMsg_Request_Params params;
PopulateParams(request_name, args, has_callback, ¶ms);
scoped_ptr<ppapi::host::ReplyMessageContext> reply_context;
if (has_callback) {
reply_context.reset(new ppapi::host::ReplyMessageContext(
context->MakeReplyMessageContext()));
}
dispatcher_owner_->dispatcher()->DispatchWithCallback(
params, dispatcher_owner_->render_frame_host(),
base::Bind(
&PepperExtensionsCommonMessageFilter::OnExtensionFunctionCompleted,
this,
base::Passed(&reply_context)));
return true;
}
}