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 // A class that manages a connection to an XMPP server.
6 
7 #ifndef JINGLE_NOTIFIER_BASE_XMPP_CONNECTION_H_
8 #define JINGLE_NOTIFIER_BASE_XMPP_CONNECTION_H_
9 
10 #include <memory>
11 
12 #include "base/gtest_prod_util.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/sequence_checker.h"
17 #include "jingle/glue/network_service_config.h"
18 #include "net/traffic_annotation/network_traffic_annotation.h"
19 #include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
20 #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
21 
22 namespace jingle_xmpp {
23 class PreXmppAuth;
24 class XmlElement;
25 class XmppClientSettings;
26 class XmppTaskParentInterface;
27 }  // namespace jingle_xmpp
28 
29 namespace jingle_glue {
30 class TaskPump;
31 }  // namespace jingle_glue
32 
33 namespace notifier {
34 
35 class WeakXmppClient;
36 
37 class XmppConnection : public sigslot::has_slots<> {
38  public:
39   class Delegate {
40    public:
41     // Called (at most once) when a connection has been established.
42     // |base_task| can be used by the client as the parent of any Task
43     // it creates as long as it is valid (i.e., non-NULL).
44     virtual void OnConnect(
45         base::WeakPtr<jingle_xmpp::XmppTaskParentInterface> base_task) = 0;
46 
47     // Called if an error has occurred (either before or after a call
48     // to OnConnect()).  No calls to the delegate will be made after
49     // this call.  Invalidates any weak pointers passed to the client
50     // by OnConnect().
51     //
52     // |error| is the code for the raised error.  |subcode| is an
53     // error-dependent subcode (0 if not applicable).  |stream_error|
54     // is non-NULL iff |error| == ERROR_STREAM.  |stream_error| is
55     // valid only for the lifetime of this function.
56     //
57     // Ideally, |error| would always be set to something that is not
58     // ERROR_NONE, but due to inconsistent error-handling this doesn't
59     // always happen.
60     virtual void OnError(jingle_xmpp::XmppEngine::Error error, int subcode,
61                          const jingle_xmpp::XmlElement* stream_error) = 0;
62 
63    protected:
64     virtual ~Delegate();
65   };
66 
67   // Does not take ownership of |delegate|, which must not be
68   // NULL.  Takes ownership of |pre_xmpp_auth|, which may be NULL.
69   //
70   // TODO(akalin): Avoid the need for |pre_xmpp_auth|.
71   XmppConnection(const jingle_xmpp::XmppClientSettings& xmpp_client_settings,
72                  jingle_glue::GetProxyResolvingSocketFactoryCallback
73                      get_socket_factory_callback,
74                  Delegate* delegate,
75                  jingle_xmpp::PreXmppAuth* pre_xmpp_auth,
76                  const net::NetworkTrafficAnnotationTag& traffic_annotation);
77 
78   // Invalidates any weak pointers passed to the delegate by
79   // OnConnect(), but does not trigger a call to the delegate's
80   // OnError() function.
81   ~XmppConnection() override;
82 
83  private:
84   FRIEND_TEST_ALL_PREFIXES(XmppConnectionTest, RaisedError);
85   FRIEND_TEST_ALL_PREFIXES(XmppConnectionTest, Connect);
86   FRIEND_TEST_ALL_PREFIXES(XmppConnectionTest, MultipleConnect);
87   FRIEND_TEST_ALL_PREFIXES(XmppConnectionTest, ConnectThenError);
88   FRIEND_TEST_ALL_PREFIXES(XmppConnectionTest,
89                            TasksDontRunAfterXmppConnectionDestructor);
90 
91   void OnStateChange(jingle_xmpp::XmppEngine::State state);
92   void OnInputLog(const char* data, int len);
93   void OnOutputLog(const char* data, int len);
94 
95   void ClearClient();
96 
97   std::unique_ptr<jingle_glue::TaskPump> task_pump_;
98   base::WeakPtr<WeakXmppClient> weak_xmpp_client_;
99   bool on_connect_called_;
100   Delegate* delegate_;
101 
102   SEQUENCE_CHECKER(sequence_checker_);
103 
104   DISALLOW_COPY_AND_ASSIGN(XmppConnection);
105 };
106 
107 }  // namespace notifier
108 
109 #endif  // JINGLE_NOTIFIER_BASE_XMPP_CONNECTION_H_
110