1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "remoting/host/it2me/it2me_native_messaging_host.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/basictypes.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback_helpers.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/run_loop.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/stringize_macros.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/threading/thread.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/values.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/net_util.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "remoting/base/auth_token_util.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "remoting/base/service_urls.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "remoting/host/chromoting_host_context.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "remoting/host/host_exit_codes.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "remoting/protocol/name_value_map.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace remoting {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const remoting::protocol::NameMapElement<It2MeHostState> kIt2MeHostStates[] = {
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kDisconnected, "DISCONNECTED"},
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kStarting, "STARTING"},
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kRequestedAccessCode, "REQUESTED_ACCESS_CODE"},
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kReceivedAccessCode, "RECEIVED_ACCESS_CODE"},
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kConnected, "CONNECTED"},
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kDisconnecting, "DISCONNECTING"},
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kError, "ERROR"},
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {kInvalidDomainError, "INVALID_DOMAIN_ERROR"}, };
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)It2MeNativeMessagingHost::It2MeNativeMessagingHost(
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<AutoThreadTaskRunner> task_runner,
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<extensions::NativeMessagingChannel> channel,
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<It2MeHostFactory> factory)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : channel_(channel.Pass()),
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      factory_(factory.Pass()),
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      weak_factory_(this) {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  weak_ptr_ = weak_factory_.GetWeakPtr();
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initialize the host context to manage the threads for the it2me host.
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The native messaging host, rather than the It2MeHost object, owns and
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // maintains the lifetime of the host context.
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_context_.reset(ChromotingHostContext::Create(task_runner).release());
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const ServiceUrls* service_urls = ServiceUrls::GetInstance();
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const bool xmpp_server_valid =
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      net::ParseHostAndPort(service_urls->xmpp_server_address(),
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            &xmpp_server_config_.host,
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            &xmpp_server_config_.port);
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(xmpp_server_valid);
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  xmpp_server_config_.use_tls = service_urls->xmpp_server_use_tls();
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  directory_bot_jid_ = service_urls->directory_bot_jid();
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)It2MeNativeMessagingHost::~It2MeNativeMessagingHost() {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (it2me_host_.get()) {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    it2me_host_->Disconnect();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    it2me_host_ = NULL;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid It2MeNativeMessagingHost::Start(const base::Closure& quit_closure) {
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!quit_closure.is_null());
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  quit_closure_ = quit_closure;
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->Start(this);
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid It2MeNativeMessagingHost::OnMessage(scoped_ptr<base::Value> message) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> message_dict(
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<base::DictionaryValue*>(message.release()));
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue());
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the client supplies an ID, it will expect it in the response. This
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // might be a string or a number, so cope with both.
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const base::Value* id;
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (message_dict->Get("id", &id))
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    response->Set("id", id->DeepCopy());
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string type;
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!message_dict->GetString("type", &type)) {
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(), "'type' not found in request.");
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response->SetString("type", type + "Response");
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (type == "hello") {
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ProcessHello(*message_dict, response.Pass());
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (type == "connect") {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ProcessConnect(*message_dict, response.Pass());
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (type == "disconnect") {
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ProcessDisconnect(*message_dict, response.Pass());
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(), "Unsupported request type: " + type);
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid It2MeNativeMessagingHost::OnDisconnect() {
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!quit_closure_.is_null())
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::ResetAndReturn(&quit_closure_).Run();
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::ProcessHello(
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::DictionaryValue& message,
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> response) const {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response->SetString("version", STRINGIZE(VERSION));
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This list will be populated when new features are added.
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::ListValue> supported_features_list(new base::ListValue());
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response->Set("supportedFeatures", supported_features_list.release());
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(response.PassAs<base::Value>());
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::ProcessConnect(
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::DictionaryValue& message,
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> response) {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (it2me_host_.get()) {
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(),
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     "Connect can be called only when disconnected.");
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  XmppSignalStrategy::XmppServerConfig xmpp_config = xmpp_server_config_;
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!message.GetString("userName", &xmpp_config.username)) {
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(), "'userName' not found in request.");
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string auth_service_with_token;
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!message.GetString("authServiceWithToken", &auth_service_with_token)) {
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(),
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     "'authServiceWithToken' not found in request.");
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ParseAuthTokenWithService(auth_service_with_token,
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            &xmpp_config.auth_token,
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            &xmpp_config.auth_service);
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (xmpp_config.auth_token.empty()) {
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        response.Pass(),
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "Invalid 'authServiceWithToken': " + auth_service_with_token);
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(NDEBUG)
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string address;
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!message.GetString("xmppServerAddress", &address)) {
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(),
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     "'xmppServerAddress' not found in request.");
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!net::ParseHostAndPort(
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)           address, &xmpp_server_config_.host, &xmpp_server_config_.port)) {
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(),
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     "Invalid 'xmppServerAddress': " + address);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!message.GetBoolean("xmppServerUseTls", &xmpp_server_config_.use_tls)) {
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(),
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     "'xmppServerUseTls' not found in request.");
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!message.GetString("directoryBotJid", &directory_bot_jid_)) {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendErrorAndExit(response.Pass(),
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     "'directoryBotJid' not found in request.");
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // !defined(NDEBUG)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create the It2Me host and start connecting.
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  it2me_host_ = factory_->CreateIt2MeHost(host_context_.get(),
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          host_context_->ui_task_runner(),
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          weak_ptr_,
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          xmpp_config,
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          directory_bot_jid_);
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  it2me_host_->Connect();
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(response.PassAs<base::Value>());
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::ProcessDisconnect(
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::DictionaryValue& message,
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> response) {
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (it2me_host_.get()) {
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    it2me_host_->Disconnect();
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    it2me_host_ = NULL;
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(response.PassAs<base::Value>());
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::SendErrorAndExit(
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> response,
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& description) const {
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LOG(ERROR) << description;
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response->SetString("type", "error");
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  response->SetString("description", description);
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(response.PassAs<base::Value>());
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Trigger a host shutdown by sending a NULL message.
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(scoped_ptr<base::Value>());
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::OnStateChanged(It2MeHostState state) {
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  state_ = state;
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> message(new base::DictionaryValue());
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message->SetString("type", "hostStateChanged");
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message->SetString("state",
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     It2MeNativeMessagingHost::HostStateToString(state));
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (state_) {
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kReceivedAccessCode:
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      message->SetString("accessCode", access_code_);
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      message->SetInteger("accessCodeLifetime",
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          access_code_lifetime_.InSeconds());
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kConnected:
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      message->SetString("client", client_username_);
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case kDisconnected:
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      client_username_.clear();
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ;
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(message.PassAs<base::Value>());
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::OnNatPolicyChanged(bool nat_traversal_enabled) {
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> message(new base::DictionaryValue());
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message->SetString("type", "natPolicyChanged");
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message->SetBoolean("natTraversalEnabled", nat_traversal_enabled);
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  channel_->SendMessage(message.PassAs<base::Value>());
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Stores the Access Code for the web-app to query.
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::OnStoreAccessCode(
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& access_code,
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::TimeDelta access_code_lifetime) {
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  access_code_ = access_code;
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  access_code_lifetime_ = access_code_lifetime;
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Stores the client user's name for the web-app to query.
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void It2MeNativeMessagingHost::OnClientAuthenticated(
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& client_username) {
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(task_runner()->BelongsToCurrentThread());
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client_username_ = client_username;
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_refptr<AutoThreadTaskRunner>
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)It2MeNativeMessagingHost::task_runner() const {
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return host_context_->ui_task_runner();
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* static */
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string It2MeNativeMessagingHost::HostStateToString(
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    It2MeHostState host_state) {
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return ValueToName(kIt2MeHostStates, host_state);
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace remoting
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
313