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 "ppapi/proxy/host_resolver_resource_base.h"
6
7#include "base/bind.h"
8#include "ppapi/c/pp_errors.h"
9#include "ppapi/proxy/error_conversion.h"
10#include "ppapi/proxy/net_address_resource.h"
11#include "ppapi/proxy/ppapi_messages.h"
12#include "ppapi/shared_impl/tracked_callback.h"
13#include "ppapi/shared_impl/var.h"
14
15namespace ppapi {
16namespace proxy {
17
18HostResolverResourceBase::HostResolverResourceBase(Connection connection,
19                                                   PP_Instance instance,
20                                                   bool private_api)
21    : PluginResource(connection, instance),
22      private_api_(private_api),
23      allow_get_results_(false) {
24  if (private_api)
25    SendCreate(BROWSER, PpapiHostMsg_HostResolver_CreatePrivate());
26  else
27    SendCreate(BROWSER, PpapiHostMsg_HostResolver_Create());
28}
29
30HostResolverResourceBase::~HostResolverResourceBase() {
31}
32
33int32_t HostResolverResourceBase::ResolveImpl(
34    const char* host,
35    uint16_t port,
36    const PP_HostResolver_Private_Hint* hint,
37    scoped_refptr<TrackedCallback> callback) {
38  allow_get_results_ = false;
39  if (!host || !hint)
40    return PP_ERROR_BADARGUMENT;
41  if (ResolveInProgress())
42    return PP_ERROR_INPROGRESS;
43
44  resolve_callback_ = callback;
45
46  HostPortPair host_port;
47  host_port.host = host;
48  host_port.port = port;
49
50  SendResolve(host_port, hint);
51  return PP_OK_COMPLETIONPENDING;
52}
53
54PP_Var HostResolverResourceBase::GetCanonicalNameImpl() {
55  if (!allow_get_results_)
56    return PP_MakeUndefined();
57
58  return StringVar::StringToPPVar(canonical_name_);
59}
60
61uint32_t HostResolverResourceBase::GetSizeImpl() {
62  if (!allow_get_results_)
63    return 0;
64  return static_cast<uint32_t>(net_address_list_.size());
65}
66
67scoped_refptr<NetAddressResource> HostResolverResourceBase::GetNetAddressImpl(
68    uint32_t index) {
69  if (!allow_get_results_ || index >= GetSizeImpl())
70    return scoped_refptr<NetAddressResource>();
71
72  return net_address_list_[index];
73}
74
75void HostResolverResourceBase::OnPluginMsgResolveReply(
76    const ResourceMessageReplyParams& params,
77    const std::string& canonical_name,
78    const std::vector<PP_NetAddress_Private>& net_address_list) {
79  if (params.result() == PP_OK) {
80    allow_get_results_ = true;
81    canonical_name_ = canonical_name;
82
83    net_address_list_.clear();
84    for (std::vector<PP_NetAddress_Private>::const_iterator iter =
85             net_address_list.begin();
86         iter != net_address_list.end();
87         ++iter) {
88      net_address_list_.push_back(
89          new NetAddressResource(connection(), pp_instance(), *iter));
90    }
91  } else {
92    canonical_name_.clear();
93    net_address_list_.clear();
94  }
95  resolve_callback_->Run(ConvertNetworkAPIErrorForCompatibility(params.result(),
96                                                                private_api_));
97}
98
99void HostResolverResourceBase::SendResolve(
100    const HostPortPair& host_port,
101    const PP_HostResolver_Private_Hint* hint) {
102  PpapiHostMsg_HostResolver_Resolve msg(host_port, *hint);
103  Call<PpapiPluginMsg_HostResolver_ResolveReply>(
104      BROWSER,
105      msg,
106      base::Bind(&HostResolverResourceBase::OnPluginMsgResolveReply,
107                 base::Unretained(this)));
108}
109
110bool HostResolverResourceBase::ResolveInProgress() const {
111  return TrackedCallback::IsPending(resolve_callback_);
112}
113
114}  // namespace proxy
115}  // namespace ppapi
116