• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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