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 JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
6 #define JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
7 
8 #include <memory>
9 
10 #include "base/compiler_specific.h"
11 #include "base/macros.h"
12 #include "jingle/notifier/base/xmpp_connection.h"
13 #include "jingle/notifier/communicator/connection_settings.h"
14 #include "jingle/notifier/communicator/login_settings.h"
15 #include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
16 
17 namespace jingle_xmpp {
18 class XmppTaskParentInterface;
19 }  // namespace jingle_xmpp
20 
21 namespace notifier {
22 
23 struct ServerInformation;
24 
25 // Handles all of the aspects of a single login attempt.  By
26 // containing this within one class, when another login attempt is
27 // made, this class can be destroyed to immediately stop the previous
28 // login attempt.
29 class SingleLoginAttempt : public XmppConnection::Delegate {
30  public:
31   // At most one delegate method will be called, depending on the
32   // result of the login attempt.  After the delegate method is
33   // called, this class won't do anything anymore until it is
34   // destroyed, at which point it will disconnect if necessary.
35   class Delegate {
36    public:
37     // Called when the login attempt is successful.
38     virtual void OnConnect(
39         base::WeakPtr<jingle_xmpp::XmppTaskParentInterface> base_task) = 0;
40 
41     // Called when the server responds with a redirect.  A new login
42     // attempt should be made to the given redirect server.
43     virtual void OnRedirect(const ServerInformation& redirect_server) = 0;
44 
45     // Called when a server rejects the client's login credentials.  A
46     // new login attempt should be made once the client provides new
47     // credentials.
48     virtual void OnCredentialsRejected() = 0;
49 
50     // Called when no server could be logged into for reasons other
51     // than redirection or rejected credentials.  A new login attempt
52     // may be created, but it should be done with exponential backoff.
53     virtual void OnSettingsExhausted() = 0;
54 
55    protected:
56     virtual ~Delegate();
57   };
58 
59   // Does not take ownership of |delegate|, which must not be NULL.
60   SingleLoginAttempt(const LoginSettings& login_settings, Delegate* delegate);
61 
62   ~SingleLoginAttempt() override;
63 
64   // XmppConnection::Delegate implementation.
65   void OnConnect(base::WeakPtr<jingle_xmpp::XmppTaskParentInterface> parent) override;
66   void OnError(jingle_xmpp::XmppEngine::Error error,
67                int error_subcode,
68                const jingle_xmpp::XmlElement* stream_error) override;
69 
70  private:
71   void TryConnect(const ConnectionSettings& new_settings);
72 
73   const LoginSettings login_settings_;
74   Delegate* const delegate_;
75   const ConnectionSettingsList settings_list_;
76   ConnectionSettingsList::const_iterator current_settings_;
77   std::unique_ptr<XmppConnection> xmpp_connection_;
78 
79   DISALLOW_COPY_AND_ASSIGN(SingleLoginAttempt);
80 };
81 
82 }  // namespace notifier
83 
84 #endif  // JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
85