Home | History | Annotate | Download | only in jingle_glue
      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 #ifndef REMOTING_JINGLE_GLUE_IQ_SENDER_H_
      6 #define REMOTING_JINGLE_GLUE_IQ_SENDER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/callback.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/gtest_prod_util.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "remoting/jingle_glue/signal_strategy.h"
     17 
     18 namespace base {
     19 class TimeDelta;
     20 }  // namespace base
     21 
     22 namespace buzz {
     23 class XmlElement;
     24 }  // namespace buzz
     25 
     26 namespace remoting {
     27 
     28 class IqRequest;
     29 class SignalStrategy;
     30 
     31 // IqSender handles sending iq requests and routing of responses to
     32 // those requests.
     33 class IqSender : public SignalStrategy::Listener {
     34  public:
     35   // Callback that is called when an Iq response is received. Called
     36   // with the |response| set to NULL in case of a timeout.
     37   typedef base::Callback<void(IqRequest* request,
     38                               const buzz::XmlElement* response)> ReplyCallback;
     39 
     40   explicit IqSender(SignalStrategy* signal_strategy);
     41   virtual ~IqSender();
     42 
     43   // Send an iq stanza. Returns an IqRequest object that represends
     44   // the request. |callback| is called when response to |stanza| is
     45   // received. Destroy the returned IqRequest to cancel the callback.
     46   // Caller must take ownership of the result. Result must be
     47   // destroyed before sender is destroyed.
     48   scoped_ptr<IqRequest> SendIq(scoped_ptr<buzz::XmlElement> stanza,
     49                                const ReplyCallback& callback);
     50 
     51   // Same as above, but also formats the message.
     52   scoped_ptr<IqRequest> SendIq(const std::string& type,
     53                                const std::string& addressee,
     54                                scoped_ptr<buzz::XmlElement> iq_body,
     55                                const ReplyCallback& callback);
     56 
     57   // SignalStrategy::Listener implementation.
     58   virtual void OnSignalStrategyStateChange(
     59       SignalStrategy::State state) OVERRIDE;
     60   virtual bool OnSignalStrategyIncomingStanza(
     61       const buzz::XmlElement* stanza) OVERRIDE;
     62 
     63  private:
     64   typedef std::map<std::string, IqRequest*> IqRequestMap;
     65   friend class IqRequest;
     66 
     67   // Helper function used to create iq stanzas.
     68   static scoped_ptr<buzz::XmlElement> MakeIqStanza(
     69       const std::string& type,
     70       const std::string& addressee,
     71       scoped_ptr<buzz::XmlElement> iq_body);
     72 
     73   // Removes |request| from the list of pending requests. Called by IqRequest.
     74   void RemoveRequest(IqRequest* request);
     75 
     76   SignalStrategy* signal_strategy_;
     77   IqRequestMap requests_;
     78 
     79   DISALLOW_COPY_AND_ASSIGN(IqSender);
     80 };
     81 
     82 // This call must only be used on the thread it was created on.
     83 class IqRequest : public  base::SupportsWeakPtr<IqRequest> {
     84  public:
     85   IqRequest(IqSender* sender, const IqSender::ReplyCallback& callback,
     86             const std::string& addressee);
     87   ~IqRequest();
     88 
     89   // Sets timeout for the request. When the timeout expires the
     90   // callback is called with the |response| set to NULL.
     91   void SetTimeout(base::TimeDelta timeout);
     92 
     93  private:
     94   friend class IqSender;
     95 
     96   void CallCallback(const buzz::XmlElement* stanza);
     97   void OnTimeout();
     98 
     99   // Called by IqSender when a response is received.
    100   void OnResponse(const buzz::XmlElement* stanza);
    101 
    102   void DeliverResponse(scoped_ptr<buzz::XmlElement> stanza);
    103 
    104   IqSender* sender_;
    105   IqSender::ReplyCallback callback_;
    106   std::string addressee_;
    107 
    108   DISALLOW_COPY_AND_ASSIGN(IqRequest);
    109 };
    110 
    111 }  // namespace remoting
    112 
    113 #endif  // REMOTING_JINGLE_GLUE_IQ_SENDER_H_
    114