1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/renderer/pepper/pepper_browser_connection.h"
6
7#include <limits>
8
9#include "base/logging.h"
10#include "content/common/view_messages.h"
11#include "content/renderer/pepper/pepper_in_process_router.h"
12#include "content/renderer/render_frame_impl.h"
13#include "ipc/ipc_message_macros.h"
14#include "ppapi/proxy/ppapi_messages.h"
15#include "ppapi/proxy/resource_message_params.h"
16
17namespace content {
18
19PepperBrowserConnection::PepperBrowserConnection(RenderFrame* render_frame)
20    : RenderFrameObserver(render_frame),
21      RenderFrameObserverTracker<PepperBrowserConnection>(render_frame),
22      next_sequence_number_(1) {
23}
24
25PepperBrowserConnection::~PepperBrowserConnection() {
26}
27
28bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) {
29  // Check if the message is an in-process reply.
30  if (PepperInProcessRouter::OnPluginMsgReceived(msg))
31    return true;
32
33  bool handled = true;
34  IPC_BEGIN_MESSAGE_MAP(PepperBrowserConnection, msg)
35    IPC_MESSAGE_HANDLER(PpapiHostMsg_CreateResourceHostsFromHostReply,
36                        OnMsgCreateResourceHostsFromHostReply)
37    IPC_MESSAGE_UNHANDLED(handled = false)
38  IPC_END_MESSAGE_MAP()
39  return handled;
40}
41
42void PepperBrowserConnection::DidCreateInProcessInstance(
43    PP_Instance instance,
44    int render_view_id,
45    const GURL& document_url,
46    const GURL& plugin_url) {
47  Send(new ViewHostMsg_DidCreateInProcessInstance(
48      instance,
49      // Browser provides the render process id.
50      PepperRendererInstanceData(0,
51                                 render_view_id,
52                                 document_url,
53                                 plugin_url)));
54}
55
56void PepperBrowserConnection::DidDeleteInProcessInstance(PP_Instance instance) {
57  Send(new ViewHostMsg_DidDeleteInProcessInstance(instance));
58}
59
60void PepperBrowserConnection::SendBrowserCreate(
61    int child_process_id,
62    PP_Instance instance,
63    const std::vector<IPC::Message>& nested_msgs,
64    const PendingResourceIDCallback& callback) {
65  int32_t sequence_number = GetNextSequence();
66  pending_create_map_[sequence_number] = callback;
67  ppapi::proxy::ResourceMessageCallParams params(0, sequence_number);
68  Send(new PpapiHostMsg_CreateResourceHostsFromHost(
69      routing_id(),
70      child_process_id,
71      params,
72      instance,
73      nested_msgs));
74}
75
76void PepperBrowserConnection::OnMsgCreateResourceHostsFromHostReply(
77    int32_t sequence_number,
78    const std::vector<int>& pending_resource_host_ids) {
79  // Check that the message is destined for the plugin this object is associated
80  // with.
81  std::map<int32_t, PendingResourceIDCallback>::iterator it =
82      pending_create_map_.find(sequence_number);
83  if (it != pending_create_map_.end()) {
84    it->second.Run(pending_resource_host_ids);
85    pending_create_map_.erase(it);
86  } else {
87    NOTREACHED();
88  }
89}
90
91int32_t PepperBrowserConnection::GetNextSequence() {
92  // Return the value with wraparound, making sure we don't make a sequence
93  // number with a 0 ID. Note that signed wraparound is undefined in C++ so we
94  // manually check.
95  int32_t ret = next_sequence_number_;
96  if (next_sequence_number_ == std::numeric_limits<int32_t>::max())
97    next_sequence_number_ = 1;  // Skip 0 which is invalid.
98  else
99    next_sequence_number_++;
100  return ret;
101}
102
103}  // namespace content
104