12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/resource_message_filter.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_errors.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/ppapi_host.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/resource_host.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace host {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace internal {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ResourceMessageFilterDeleteTraits::Destruct(
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ResourceMessageFilter* filter) {
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!filter->deletion_message_loop_proxy_->BelongsToCurrentThread()) {
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // During shutdown the object may not be deleted, but it should be okay to
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // leak in that case.
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    filter->deletion_message_loop_proxy_->DeleteSoon(FROM_HERE, filter);
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delete filter;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace internal
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceMessageFilter::ResourceMessageFilter()
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : deletion_message_loop_proxy_(
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::MessageLoop::current()->message_loop_proxy()),
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reply_thread_message_loop_proxy_(
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::MessageLoop::current()->message_loop_proxy()),
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resource_host_(NULL) {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceMessageFilter::ResourceMessageFilter(
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> reply_thread_message_loop_proxy)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : deletion_message_loop_proxy_(
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::MessageLoop::current()->message_loop_proxy()),
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reply_thread_message_loop_proxy_(reply_thread_message_loop_proxy),
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_host_(NULL) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceMessageFilter::~ResourceMessageFilter() {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceMessageFilter::OnFilterAdded(ResourceHost* resource_host) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_host_ = resource_host;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceMessageFilter::OnFilterDestroyed() {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_host_ = NULL;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceMessageFilter::HandleMessage(const IPC::Message& msg,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          HostMessageContext* context) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::TaskRunner> runner = OverrideTaskRunnerForMessage(msg);
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (runner.get()) {
66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (runner->RunsTasksOnCurrentThread()) {
67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      DispatchMessage(msg, *context);
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // TODO(raymes): We need to make a copy so the context can be used on
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // other threads. It would be better to have a thread-safe refcounted
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // context.
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      HostMessageContext context_copy = *context;
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      runner->PostTask(FROM_HERE, base::Bind(
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          &ResourceMessageFilter::DispatchMessage, this, msg, context_copy));
75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceMessageFilter::SendReply(const ReplyMessageContext& context,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const IPC::Message& msg) {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reply_thread_message_loop_proxy_->BelongsToCurrentThread()) {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reply_thread_message_loop_proxy_->PostTask(FROM_HERE,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ResourceMessageFilter::SendReply, this, context, msg));
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource_host_)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_host_->SendReply(context, msg);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::TaskRunner>
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceMessageFilter::DispatchMessage(const IPC::Message& msg,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            HostMessageContext context) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunMessageHandlerAndReply(msg, &context);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace host
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ppapi
105