summaryrefslogtreecommitdiffstats
path: root/content/child/webmessageportchannel_impl.h
blob: b5c8e7bf454c563b33f0f9bafe5e24c41104ebba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_CHILD_WEBMESSAGEPORTCHANNEL_IMPL_H_
#define CONTENT_CHILD_WEBMESSAGEPORTCHANNEL_IMPL_H_

#include <queue>
#include <vector>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
#include "content/public/common/message_port_types.h"
#include "ipc/ipc_listener.h"
#include "third_party/WebKit/public/platform/WebMessagePortChannel.h"

namespace base {
class SingleThreadTaskRunner;
class Value;
}

namespace content {
class ChildThread;

// This is thread safe.
class WebMessagePortChannelImpl
    : public blink::WebMessagePortChannel,
      public IPC::Listener,
      public base::RefCountedThreadSafe<WebMessagePortChannelImpl> {
 public:
  explicit WebMessagePortChannelImpl(
      const scoped_refptr<base::SingleThreadTaskRunner>&
          main_thread_task_runner);
  WebMessagePortChannelImpl(
      int route_id,
      const TransferredMessagePort& port,
      const scoped_refptr<base::SingleThreadTaskRunner>&
          main_thread_task_runner);

  static void CreatePair(
      const scoped_refptr<base::SingleThreadTaskRunner>&
          main_thread_task_runner,
      blink::WebMessagePortChannel** channel1,
      blink::WebMessagePortChannel** channel2);

  // Extracts port IDs for passing on to the browser process, and queues any
  // received messages.
  static std::vector<TransferredMessagePort> ExtractMessagePortIDs(
      scoped_ptr<blink::WebMessagePortChannelArray> channels);

  // Extracts port IDs for passing on to the browser process, and queues any
  // received messages.
  static std::vector<TransferredMessagePort> ExtractMessagePortIDs(
      const blink::WebMessagePortChannelArray& channels);

  // Extracts port IDs for passing on to the browser process, but doesn't
  // send a separate IPC to the browser to initiate queueing messages. Instead
  // calling code is responsible for initiating the queueing in the browser
  // process. This is useful when transfering ports over an IPC channel that
  // does not share ordering guarentees with regular IPC.
  static std::vector<TransferredMessagePort>
  ExtractMessagePortIDsWithoutQueueing(
      scoped_ptr<blink::WebMessagePortChannelArray> channels);

  // Creates WebMessagePortChannelImpl instances for port IDs passed in from the
  // browser process.
  static blink::WebMessagePortChannelArray CreatePorts(
      const std::vector<TransferredMessagePort>& message_ports,
      const std::vector<int>& new_routing_ids,
      const scoped_refptr<base::SingleThreadTaskRunner>&
          main_thread_task_runner);

  // Queues received and incoming messages until there are no more in-flight
  // messages, then sends all of them to the browser process.
  void QueueMessages();
  int message_port_id() const { return message_port_id_; }

 private:
  friend class base::RefCountedThreadSafe<WebMessagePortChannelImpl>;
  ~WebMessagePortChannelImpl() override;

  // WebMessagePortChannel implementation.
  void setClient(blink::WebMessagePortChannelClient* client) override;
  void destroy() override;
  void postMessage(const blink::WebString& message,
                   blink::WebMessagePortChannelArray* channels_ptr) override;
  bool tryGetMessage(blink::WebString* message,
                     blink::WebMessagePortChannelArray& channels) override;

  void Init();
  void Entangle(scoped_refptr<WebMessagePortChannelImpl> channel);
  void Send(IPC::Message* message);
  void PostMessage(const MessagePortMessage& message,
                   scoped_ptr<blink::WebMessagePortChannelArray> channels);

  // IPC::Listener implementation.
  bool OnMessageReceived(const IPC::Message& message) override;

  void OnMessage(const MessagePortMessage& message,
                 const std::vector<TransferredMessagePort>& sent_message_ports,
                 const std::vector<int>& new_routing_ids);
  void OnMessagesQueued();

  struct Message {
    Message();
    ~Message();

    MessagePortMessage message;
    blink::WebMessagePortChannelArray ports;
  };

  typedef std::queue<Message> MessageQueue;
  MessageQueue message_queue_;

  blink::WebMessagePortChannelClient* client_;
  base::Lock lock_;  // Locks access to above.

  int route_id_;  // The routing id for this object.
  int message_port_id_;  // A globally unique identifier for this message port.
  // Flag to indicate if messages should be sent to the browser process as
  // base::Value instances as opposed to being serialized using the default
  // blink::WebSerializedScriptValue.
  bool send_messages_as_values_;
  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;

  DISALLOW_COPY_AND_ASSIGN(WebMessagePortChannelImpl);
};

}  // namespace content

#endif  // CONTENT_CHILD_WEBMESSAGEPORTCHANNEL_IMPL_H_