15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <string.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/cpp/instance_handle.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/cpp/net_address.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/cpp/private/host_resolver_private.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/cpp/private/net_address_private.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IsBigEndian() {
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  union {
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32_t integer32;
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint8_t integer8[4];
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } data = { 0x01020304 };
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return data.integer8[0] == 1;
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kActionTimeoutMs = 10000;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const PPB_Testing_Private* GetTestingInterface() {
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static const PPB_Testing_Private* g_testing_interface =
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      static_cast<const PPB_Testing_Private*>(
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          pp::Module::Get()->GetBrowserInterface(
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              PPB_TESTING_PRIVATE_INTERFACE));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_testing_interface;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ReportError(const char* method, int32_t error) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char error_as_string[12];
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sprintf(error_as_string, "%d", static_cast<int>(error));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result = method + std::string(" failed with error: ") +
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_as_string;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformSleep(int duration_ms) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::Sleep(duration_ms);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  usleep(duration_ms * 1000);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host || !port)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PPB_Testing_Private* testing = GetTestingInterface();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!testing)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_URLComponents_Dev components;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Var pp_url(pp::PASS_REF,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 testing->GetDocumentURL(instance, &components));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pp_url.is_string())
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url = pp_url.AsString();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (components.host.len < 0)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host->assign(url.substr(components.host.begin, components.host.len));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (components.port.len <= 0)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i = atoi(url.substr(components.port.begin, components.port.len).c_str());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i < 0 || i > 65535)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *port = static_cast<uint16_t>(i);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint16_t ConvertFromNetEndian16(uint16_t x) {
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (IsBigEndian())
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return (x << 8) | (x >> 8);
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint16_t ConvertToNetEndian16(uint16_t x) {
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (IsBigEndian())
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return x;
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return (x << 8) | (x >> 8);
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool EqualNetAddress(const pp::NetAddress& addr1, const pp::NetAddress& addr2) {
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (addr1.GetFamily() == PP_NETADDRESS_FAMILY_UNSPECIFIED ||
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      addr2.GetFamily() == PP_NETADDRESS_FAMILY_UNSPECIFIED) {
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (addr1.GetFamily() == PP_NETADDRESS_FAMILY_IPV4) {
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    PP_NetAddress_IPv4 ipv4_addr1, ipv4_addr2;
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!addr1.DescribeAsIPv4Address(&ipv4_addr1) ||
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        !addr2.DescribeAsIPv4Address(&ipv4_addr2)) {
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return false;
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return ipv4_addr1.port == ipv4_addr2.port &&
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)           !memcmp(ipv4_addr1.addr, ipv4_addr2.addr, sizeof(ipv4_addr1.addr));
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    PP_NetAddress_IPv6 ipv6_addr1, ipv6_addr2;
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!addr1.DescribeAsIPv6Address(&ipv6_addr1) ||
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        !addr2.DescribeAsIPv6Address(&ipv6_addr2)) {
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return false;
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return ipv6_addr1.port == ipv6_addr2.port &&
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)           !memcmp(ipv6_addr1.addr, ipv6_addr2.addr, sizeof(ipv6_addr1.addr));
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ResolveHost(PP_Instance instance,
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 const std::string& host,
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 uint16_t port,
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 pp::NetAddress* addr) {
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(yzshen): Change to use the public host resolver once it is supported.
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pp::InstanceHandle instance_handle(instance);
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  pp::HostResolverPrivate host_resolver(instance_handle);
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PP_HostResolver_Private_Hint hint =
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      { PP_NETADDRESSFAMILY_PRIVATE_UNSPECIFIED, 0 };
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TestCompletionCallback callback(instance);
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  callback.WaitForResult(
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      host_resolver.Resolve(host, port, hint, callback.GetCallback()));
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PP_NetAddress_Private addr_private;
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (callback.result() != PP_OK || host_resolver.GetSize() == 0 ||
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      !host_resolver.GetNetAddress(0, &addr_private)) {
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (pp::NetAddressPrivate::GetFamily(addr_private)) {
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case PP_NETADDRESSFAMILY_PRIVATE_IPV4: {
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      PP_NetAddress_IPv4 ipv4_addr;
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ipv4_addr.port = ConvertToNetEndian16(
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          pp::NetAddressPrivate::GetPort(addr_private));
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!pp::NetAddressPrivate::GetAddress(addr_private, ipv4_addr.addr,
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                             sizeof(ipv4_addr.addr))) {
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      *addr = pp::NetAddress(instance_handle, ipv4_addr);
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case PP_NETADDRESSFAMILY_PRIVATE_IPV6: {
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      PP_NetAddress_IPv6 ipv6_addr;
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ipv6_addr.port = ConvertToNetEndian16(
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          pp::NetAddressPrivate::GetPort(addr_private));
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!pp::NetAddressPrivate::GetAddress(addr_private, ipv6_addr.addr,
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                             sizeof(ipv6_addr.addr))) {
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      *addr = pp::NetAddress(instance_handle, ipv6_addr);
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    default: {
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return false;
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool ReplacePort(PP_Instance instance,
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 const pp::NetAddress& input_addr,
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 uint16_t port,
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 pp::NetAddress* output_addr) {
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  switch (input_addr.GetFamily()) {
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_IPV4: {
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      PP_NetAddress_IPv4 ipv4_addr;
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (!input_addr.DescribeAsIPv4Address(&ipv4_addr))
19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return false;
19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ipv4_addr.port = ConvertToNetEndian16(port);
19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *output_addr = pp::NetAddress(pp::InstanceHandle(instance), ipv4_addr);
19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_IPV6: {
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      PP_NetAddress_IPv6 ipv6_addr;
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (!input_addr.DescribeAsIPv6Address(&ipv6_addr))
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return false;
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ipv6_addr.port = ConvertToNetEndian16(port);
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *output_addr = pp::NetAddress(pp::InstanceHandle(instance), ipv6_addr);
20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    default: {
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return false;
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint16_t GetPort(const pp::NetAddress& addr) {
21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  switch (addr.GetFamily()) {
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_IPV4: {
21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      PP_NetAddress_IPv4 ipv4_addr;
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (!addr.DescribeAsIPv4Address(&ipv4_addr))
21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return 0;
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return ConvertFromNetEndian16(ipv4_addr.port);
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_IPV6: {
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      PP_NetAddress_IPv6 ipv6_addr;
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (!addr.DescribeAsIPv6Address(&ipv6_addr))
22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return 0;
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return ConvertFromNetEndian16(ipv6_addr.port);
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    default: {
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return 0;
22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NestedEvent::Wait() {
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't allow nesting more than once; it doesn't work with the code as-is,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and probably is a bad idea most of the time anyway.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_DCHECK(!waiting_);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (signalled_)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  waiting_ = true;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!signalled_)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetTestingInterface()->RunMessageLoop(instance_);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  waiting_ = false;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NestedEvent::Signal() {
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pp::Module::Get()->core()->IsMainThread())
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SignalOnMainThread();
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostSignal(0);
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NestedEvent::PostSignal(int32_t wait_ms) {
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::Module::Get()->core()->CallOnMainThread(
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      wait_ms,
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pp::CompletionCallback(&SignalThunk, this),
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      0);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NestedEvent::Reset() {
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It doesn't make sense to reset when we're still waiting.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_DCHECK(!waiting_);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  signalled_ = false;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NestedEvent::SignalOnMainThread() {
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signalled_ = true;
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (waiting_)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GetTestingInterface()->QuitMessageLoop(instance_);
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NestedEvent::SignalThunk(void* event, int32_t /* result */) {
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static_cast<NestedEvent*>(event)->SignalOnMainThread();
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompletionCallback::TestCompletionCallback(PP_Instance instance)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : wait_for_result_called_(false),
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      have_result_(false),
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(PP_OK_COMPLETIONPENDING),
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(dmichael): The default should probably be PP_REQUIRED, but this is
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //                 what the tests currently expect.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_type_(PP_OPTIONAL),
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      post_quit_task_(false),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_(instance),
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(NULL) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompletionCallback::TestCompletionCallback(PP_Instance instance,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bool force_async)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : wait_for_result_called_(false),
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      have_result_(false),
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(PP_OK_COMPLETIONPENDING),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_type_(force_async ? PP_REQUIRED : PP_OPTIONAL),
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      post_quit_task_(false),
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_(instance),
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(NULL) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompletionCallback::TestCompletionCallback(PP_Instance instance,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               CallbackType callback_type)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : wait_for_result_called_(false),
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      have_result_(false),
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(PP_OK_COMPLETIONPENDING),
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_type_(callback_type),
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      post_quit_task_(false),
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_(instance),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(NULL) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompletionCallback::WaitForResult(int32_t result) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_DCHECK(!wait_for_result_called_);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_for_result_called_ = true;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  errors_.clear();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == PP_OK_COMPLETIONPENDING) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!have_result_) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      post_quit_task_ = true;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RunMessageLoop();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (callback_type_ == PP_BLOCKING) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      errors_.assign(
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ReportError("TestCompletionCallback: Call did not run synchronously "
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "when passed a blocking completion callback!",
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      result_));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = result;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    have_result_ = true;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (callback_type_ == PP_REQUIRED) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      errors_.assign(
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ReportError("TestCompletionCallback: Call ran synchronously when "
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "passed a required completion callback!",
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      result_));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_DCHECK(have_result_ == true);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompletionCallback::WaitForAbortResult(int32_t result) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WaitForResult(result);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t final_result = result_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == PP_OK_COMPLETIONPENDING) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (final_result != PP_ERROR_ABORTED) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      errors_.assign(
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ReportError("TestCompletionCallback: Expected PP_ERROR_ABORTED or "
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "PP_OK. Ran asynchronously.",
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      final_result));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (result < PP_OK) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors_.assign(
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReportError("TestCompletionCallback: Expected PP_ERROR_ABORTED or "
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "non-error response. Ran synchronously.",
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    result));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pp::CompletionCallback TestCompletionCallback::GetCallback() {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t flags = 0;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (callback_type_ == PP_BLOCKING)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pp::CompletionCallback();
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (callback_type_ == PP_OPTIONAL)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags = PP_COMPLETIONCALLBACK_FLAG_OPTIONAL;
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_loop_ = pp::MessageLoop::GetCurrent();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pp::CompletionCallback(&TestCompletionCallback::Handler,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const_cast<TestCompletionCallback*>(this),
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                flags);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompletionCallback::Reset() {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_for_result_called_ = false;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_ = PP_OK_COMPLETIONPENDING;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  have_result_ = false;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  post_quit_task_ = false;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = NULL;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  errors_.clear();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompletionCallback::Handler(void* user_data, int32_t result) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback* callback =
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestCompletionCallback*>(user_data);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this check fails, it means that the callback was invoked twice or that
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the PPAPI call completed synchronously, but also ran the callback.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_DCHECK(!callback->have_result_);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback->result_ = result;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback->have_result_ = true;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (callback->delegate_)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback->delegate_->OnCallback(user_data, result);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (callback->post_quit_task_) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback->post_quit_task_ = false;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback->QuitMessageLoop();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback->target_loop_ != pp::MessageLoop::GetCurrent()) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note, in-process, loop_ and GetCurrent() will both be NULL, so should
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // still be equal.
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback->errors_.assign(
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReportError("TestCompletionCallback: Callback ran on the wrong message "
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "loop!",
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    result));
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompletionCallback::RunMessageLoop() {
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::MessageLoop loop(pp::MessageLoop::GetCurrent());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we don't have a message loop, we're probably running in process, where
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PPB_MessageLoop is not supported. Just use the Testing message loop.
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (loop.is_null() || loop == pp::MessageLoop::GetForMainThread())
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetTestingInterface()->RunMessageLoop(instance_);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    loop.Run();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompletionCallback::QuitMessageLoop() {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::MessageLoop loop(pp::MessageLoop::GetCurrent());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we don't have a message loop, we're probably running in process, where
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PPB_MessageLoop is not supported. Just use the Testing message loop.
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (loop.is_null() || loop == pp::MessageLoop::GetForMainThread()) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetTestingInterface()->QuitMessageLoop(instance_);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool should_quit = false;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    loop.PostQuit(should_quit);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
427