summaryrefslogtreecommitdiff
path: root/chromium/content/child/webmessageportchannel_impl.cc
blob: 3c5e8d90ed75c5523c12f432d50589b24f897a5d (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
// Copyright (c) 2011 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.

#include "content/child/webmessageportchannel_impl.h"

#include <stddef.h>

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "third_party/WebKit/public/platform/WebMessagePortChannelClient.h"
#include "third_party/WebKit/public/platform/WebString.h"

using blink::WebMessagePortChannel;
using blink::WebMessagePortChannelArray;
using blink::WebMessagePortChannelClient;
using blink::WebString;

namespace content {

WebMessagePortChannelImpl::~WebMessagePortChannelImpl() {
  setClient(nullptr);
}

WebMessagePortChannelImpl::WebMessagePortChannelImpl(
    MessagePort message_port)
    : port_(message_port.ReleaseHandle()) {
}

// static
void WebMessagePortChannelImpl::CreatePair(
    blink::WebMessagePortChannel** channel1,
    blink::WebMessagePortChannel** channel2) {
  mojo::MessagePipe pipe;
  *channel1 = new WebMessagePortChannelImpl(std::move(pipe.handle0));
  *channel2 = new WebMessagePortChannelImpl(std::move(pipe.handle1));
}

// static
std::vector<MessagePort>
WebMessagePortChannelImpl::ExtractMessagePorts(
    WebMessagePortChannelArray channels) {
  std::vector<MessagePort> message_ports(channels.size());
  for (size_t i = 0; i < channels.size(); ++i) {
    WebMessagePortChannelImpl* channel_impl =
        static_cast<WebMessagePortChannelImpl*>(channels[i].get());
    message_ports[i] = channel_impl->ReleaseMessagePort();
    DCHECK(message_ports[i].GetHandle().is_valid());
  }
  return message_ports;
}

// static
WebMessagePortChannelArray
WebMessagePortChannelImpl::CreateFromMessagePorts(
    const std::vector<MessagePort>& message_ports) {
  WebMessagePortChannelArray channels(message_ports.size());
  for (size_t i = 0; i < message_ports.size(); ++i)
    channels[i] = base::MakeUnique<WebMessagePortChannelImpl>(message_ports[i]);
  return channels;
}

// static
WebMessagePortChannelArray
WebMessagePortChannelImpl::CreateFromMessagePipeHandles(
    std::vector<mojo::ScopedMessagePipeHandle> handles) {
  WebMessagePortChannelArray channels(handles.size());
  for (size_t i = 0; i < handles.size(); ++i) {
    channels[i] = base::MakeUnique<WebMessagePortChannelImpl>(
        MessagePort(std::move(handles[i])));
  }
  return channels;
}

MessagePort WebMessagePortChannelImpl::ReleaseMessagePort() {
  return MessagePort(port_.ReleaseHandle());
}

WebMessagePortChannelImpl::WebMessagePortChannelImpl(
    mojo::ScopedMessagePipeHandle handle)
    : port_(std::move(handle)) {
}

void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) {
  if (client) {
    port_.SetCallback(
        base::Bind(&WebMessagePortChannelClient::messageAvailable,
                   base::Unretained(client)));
  } else {
    port_.ClearCallback();
  }
}

void WebMessagePortChannelImpl::postMessage(
    const WebString& encoded_message,
    WebMessagePortChannelArray channels) {
  std::vector<MessagePort> ports;
  if (!channels.isEmpty()) {
    ports.resize(channels.size());
    for (size_t i = 0; i < channels.size(); ++i) {
      ports[i] = static_cast<WebMessagePortChannelImpl*>(channels[i].get())->
          ReleaseMessagePort();
    }
  }
  port_.PostMessage(encoded_message.utf16(), std::move(ports));
}

bool WebMessagePortChannelImpl::tryGetMessage(
    WebString* encoded_message,
    WebMessagePortChannelArray& channels) {
  base::string16 buffer;
  std::vector<MessagePort> ports;
  if (!port_.GetMessage(&buffer, &ports))
    return false;

  *encoded_message = WebString::fromUTF16(buffer);

  if (!ports.empty()) {
    channels = WebMessagePortChannelArray(ports.size());
    for (size_t i = 0; i < ports.size(); ++i)
      channels[i] = base::MakeUnique<WebMessagePortChannelImpl>(ports[i]);
  }
  return true;
}

}  // namespace content