Home | History | Annotate | Download | only in host
      1 // Copyright (c) 2012 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 "remoting/host/log_to_server.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop_proxy.h"
      9 #include "remoting/base/constants.h"
     10 #include "remoting/host/host_status_monitor.h"
     11 #include "remoting/host/server_log_entry_host.h"
     12 #include "remoting/jingle_glue/iq_sender.h"
     13 #include "remoting/jingle_glue/server_log_entry.h"
     14 #include "remoting/jingle_glue/signal_strategy.h"
     15 #include "remoting/protocol/transport.h"
     16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
     17 #include "third_party/libjingle/source/talk/xmpp/constants.h"
     18 
     19 using buzz::QName;
     20 using buzz::XmlElement;
     21 
     22 namespace remoting {
     23 
     24 LogToServer::LogToServer(base::WeakPtr<HostStatusMonitor> monitor,
     25                          ServerLogEntry::Mode mode,
     26                          SignalStrategy* signal_strategy,
     27                          const std::string& directory_bot_jid)
     28     : monitor_(monitor),
     29       mode_(mode),
     30       signal_strategy_(signal_strategy),
     31       directory_bot_jid_(directory_bot_jid) {
     32   monitor_->AddStatusObserver(this);
     33   signal_strategy_->AddListener(this);
     34 }
     35 
     36 LogToServer::~LogToServer() {
     37   signal_strategy_->RemoveListener(this);
     38   if (monitor_.get())
     39     monitor_->RemoveStatusObserver(this);
     40 }
     41 
     42 void LogToServer::LogSessionStateChange(const std::string& jid,
     43                                         bool connected) {
     44   DCHECK(CalledOnValidThread());
     45 
     46   scoped_ptr<ServerLogEntry> entry(
     47       MakeLogEntryForSessionStateChange(connected));
     48   AddHostFieldsToLogEntry(entry.get());
     49   entry->AddModeField(mode_);
     50 
     51   if (connected) {
     52     DCHECK(connection_route_type_.count(jid) == 1);
     53     AddConnectionTypeToLogEntry(entry.get(), connection_route_type_[jid]);
     54   }
     55   Log(*entry.get());
     56 }
     57 
     58 void LogToServer::OnSignalStrategyStateChange(SignalStrategy::State state) {
     59   DCHECK(CalledOnValidThread());
     60 
     61   if (state == SignalStrategy::CONNECTED) {
     62     iq_sender_.reset(new IqSender(signal_strategy_));
     63     SendPendingEntries();
     64   } else if (state == SignalStrategy::DISCONNECTED) {
     65     iq_sender_.reset();
     66   }
     67 }
     68 
     69 bool LogToServer::OnSignalStrategyIncomingStanza(
     70     const buzz::XmlElement* stanza) {
     71   return false;
     72 }
     73 
     74 void LogToServer::OnClientConnected(const std::string& jid) {
     75   DCHECK(CalledOnValidThread());
     76   LogSessionStateChange(jid, true);
     77 }
     78 
     79 void LogToServer::OnClientDisconnected(const std::string& jid) {
     80   DCHECK(CalledOnValidThread());
     81   LogSessionStateChange(jid, false);
     82   connection_route_type_.erase(jid);
     83 }
     84 
     85 void LogToServer::OnClientRouteChange(const std::string& jid,
     86                                       const std::string& channel_name,
     87                                       const protocol::TransportRoute& route) {
     88   // Store connection type for the video channel. It is logged later
     89   // when client authentication is finished.
     90   if (channel_name == kVideoChannelName) {
     91     connection_route_type_[jid] = route.type;
     92   }
     93 }
     94 
     95 void LogToServer::Log(const ServerLogEntry& entry) {
     96   pending_entries_.push_back(entry);
     97   SendPendingEntries();
     98 }
     99 
    100 void LogToServer::SendPendingEntries() {
    101   if (iq_sender_ == NULL) {
    102     return;
    103   }
    104   if (pending_entries_.empty()) {
    105     return;
    106   }
    107   // Make one stanza containing all the pending entries.
    108   scoped_ptr<XmlElement> stanza(ServerLogEntry::MakeStanza());
    109   while (!pending_entries_.empty()) {
    110     ServerLogEntry& entry = pending_entries_.front();
    111     stanza->AddElement(entry.ToStanza().release());
    112     pending_entries_.pop_front();
    113   }
    114   // Send the stanza to the server.
    115   scoped_ptr<IqRequest> req = iq_sender_->SendIq(
    116       buzz::STR_SET, directory_bot_jid_, stanza.Pass(),
    117       IqSender::ReplyCallback());
    118   // We ignore any response, so let the IqRequest be destroyed.
    119   return;
    120 }
    121 
    122 }  // namespace remoting
    123