1 // Copyright 2014 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.
5 package org
.chromium
.chromoting
;
7 import org
.chromium
.chromoting
.jni
.JniInterface
;
10 * This class manages making a connection to a host, with logic for reloading the host list and
11 * retrying the connection in the case of a stale host JID.
13 public class SessionConnector
implements JniInterface
.ConnectionListener
,
14 HostListLoader
.Callback
{
15 private JniInterface
.ConnectionListener mConnectionCallback
;
16 private HostListLoader
.Callback mHostListCallback
;
17 private HostListLoader mHostListLoader
;
18 private SessionAuthenticator mAuthenticator
;
20 private String mAccountName
;
21 private String mAuthToken
;
23 /** Used to find the HostInfo from the returned array after the host list is reloaded. */
24 private String mHostId
;
26 private String mHostJabberId
;
29 * Tracks whether the connection has been established. Auto-reloading and reconnecting should
30 * only happen if connection has not yet occurred.
32 private boolean mConnected
;
35 * @param connectionCallback Object to be notified on connection success/failure.
36 * @param hostListCallback Object to be notified whenever the host list is reloaded.
37 * @param hostListLoader The object used for reloading the host list.
39 public SessionConnector(JniInterface
.ConnectionListener connectionCallback
,
40 HostListLoader
.Callback hostListCallback
, HostListLoader hostListLoader
) {
41 mConnectionCallback
= connectionCallback
;
42 mHostListCallback
= hostListCallback
;
43 mHostListLoader
= hostListLoader
;
46 /** Initiates a connection to the host. */
47 public void connectToHost(String accountName
, String authToken
, HostInfo host
,
48 SessionAuthenticator authenticator
) {
49 mAccountName
= accountName
;
50 mAuthToken
= authToken
;
52 mHostJabberId
= host
.jabberId
;
53 mAuthenticator
= authenticator
;
55 if (hostIncomplete(host
)) {
56 // These keys might not be present in a newly-registered host, so treat this as a
57 // connection failure and reload the host list.
58 reloadHostListAndConnect();
62 JniInterface
.connectToHost(accountName
, authToken
, host
.jabberId
, host
.id
, host
.publicKey
,
63 this, mAuthenticator
);
66 private static boolean hostIncomplete(HostInfo host
) {
67 return host
.jabberId
.isEmpty() || host
.publicKey
.isEmpty();
70 private void reloadHostListAndConnect() {
71 mHostListLoader
.retrieveHostList(mAuthToken
, this);
75 public void onConnectionState(JniInterface
.ConnectionListener
.State state
,
76 JniInterface
.ConnectionListener
.Error error
) {
77 boolean connected
= mConnected
;
78 mConnected
= (state
== JniInterface
.ConnectionListener
.State
.CONNECTED
);
80 if (!connected
&& state
== JniInterface
.ConnectionListener
.State
.FAILED
81 && error
== JniInterface
.ConnectionListener
.Error
.PEER_IS_OFFLINE
) {
82 // The host is offline, which may mean the JID is out of date, so refresh the host list
83 // and try to connect again.
84 reloadHostListAndConnect();
86 // Pass the state/error back to the caller.
87 mConnectionCallback
.onConnectionState(state
, error
);
92 public void onHostListReceived(HostInfo
[] hosts
) {
93 // Notify the caller, so the UI is updated.
94 mHostListCallback
.onHostListReceived(hosts
);
96 HostInfo foundHost
= null;
97 for (HostInfo host
: hosts
) {
98 if (host
.id
.equals(mHostId
)) {
104 if (foundHost
== null || foundHost
.jabberId
.equals(mHostJabberId
)
105 || hostIncomplete(foundHost
)) {
106 // Cannot reconnect to this host, or there's no point in trying because the JID is
107 // unchanged, so report the original failure to the client.
108 mConnectionCallback
.onConnectionState(JniInterface
.ConnectionListener
.State
.FAILED
,
109 JniInterface
.ConnectionListener
.Error
.PEER_IS_OFFLINE
);
111 // Reconnect to the host, but use the original callback directly, instead of this
112 // wrapper object, so the host list is not loaded again.
113 JniInterface
.connectToHost(mAccountName
, mAuthToken
, foundHost
.jabberId
,
114 foundHost
.id
, foundHost
.publicKey
, mConnectionCallback
, mAuthenticator
);
119 public void onError(HostListLoader
.Error error
) {
120 // Connection failed and reloading the host list also failed, so report the connection
122 mConnectionCallback
.onConnectionState(JniInterface
.ConnectionListener
.State
.FAILED
,
123 JniInterface
.ConnectionListener
.Error
.PEER_IS_OFFLINE
);
125 // Notify the caller that the host list failed to load, so the UI is updated accordingly.
126 // The currently-displayed host list is not likely to be valid any more.
127 mHostListCallback
.onError(error
);