From e7651315dfbe0fac721b29d8710c39e23bcf9a02 Mon Sep 17 00:00:00 2001 From: Steven Luo Date: Wed, 29 Jun 2011 01:19:02 -0700 Subject: [PATCH] Make reconnections actually work At the moment, the reconnect feature is somewhat glitchy, popping up multiple reconnect prompts even if a reconnection succeeds, and occasionally causing crashes. A successful reconnection results in the conversation history being cleared, which is an annoying outcome when connected over an unreliable network. This patch does the following: * Keep track of whether a reconnect dialog is active, to prevent multiple dialogs from opening. * Introduce a new field to the Server object, mayReconnect, which is used to keep track of whether a reconnection should be attempted in the event of a disconnection. It's set to "true" when we connect to a server, and "false" if the user asks for a disconnection. * Prevent the clearing of active conversations and conversation history on disconnect, unless the user specifically asked for the disconnect. * Keep the IRCService running even when no servers are connected, unless the user has disconnected from all servers herself. This is needed for reliable auto-reconnects (see next patch), but has the side effect of keeping conversation history around even if the activity isn't open when a disconnect happens. --- .../yaaic/activity/ConversationActivity.java | 25 +++++++++++-------- .../org/yaaic/activity/ServersActivity.java | 4 ++- .../src/org/yaaic/irc/IRCConnection.java | 4 +-- application/src/org/yaaic/irc/IRCService.java | 2 +- application/src/org/yaaic/model/Server.java | 17 +++++++++++++ 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/application/src/org/yaaic/activity/ConversationActivity.java b/application/src/org/yaaic/activity/ConversationActivity.java index 542dfbb..2c60d33 100644 --- a/application/src/org/yaaic/activity/ConversationActivity.java +++ b/application/src/org/yaaic/activity/ConversationActivity.java @@ -121,6 +121,8 @@ public class ConversationActivity extends Activity implements ServiceConnection, private int historySize; + private boolean reconnectDialogActive = false; + OnKeyListener inputKeyListener = new OnKeyListener() { /** * On key pressed (input line) @@ -392,6 +394,8 @@ public class ConversationActivity extends Activity implements ServiceConnection, if (server.getStatus() == Status.PRE_CONNECTING && getIntent().hasExtra("connect")) { server.setStatus(Status.CONNECTING); binder.connect(server); + } else { + onStatusUpdate(); } } @@ -441,6 +445,7 @@ public class ConversationActivity extends Activity implements ServiceConnection, switch (item.getItemId()) { case R.id.disconnect: server.setStatus(Status.DISCONNECTED); + server.setMayReconnect(false); binder.getService().getConnection(serverId).quitServer(); server.clearConversations(); setResult(RESULT_OK); @@ -604,10 +609,6 @@ public class ConversationActivity extends Activity implements ServiceConnection, input.setEnabled(false); if (server.getStatus() == Status.CONNECTING) { - deckAdapter.clearConversations(); - Conversation serverInfo = server.getConversation(ServerInfo.DEFAULT_NAME); - serverInfo.setHistorySize(historySize); - deckAdapter.addItem(serverInfo); return; } @@ -616,27 +617,31 @@ public class ConversationActivity extends Activity implements ServiceConnection, return; } - if (!binder.getService().getSettings().isReconnectEnabled()) { + if (!binder.getService().getSettings().isReconnectEnabled() && !reconnectDialogActive) { + reconnectDialogActive = true; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(getResources().getString(R.string.reconnect_after_disconnect, server.getTitle())) .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { + if (!server.isDisconnected()) { + reconnectDialogActive = false; + return; + } binder.getService().getConnection(server.getId()).setAutojoinChannels( server.getCurrentChannelNames() ); - server.clearConversations(); - deckAdapter.clearConversations(); - Conversation serverInfo = server.getConversation(ServerInfo.DEFAULT_NAME); - serverInfo.setHistorySize(historySize); - deckAdapter.addItem(serverInfo); + server.setStatus(Status.CONNECTING); binder.connect(server); + reconnectDialogActive = false; } }) .setNegativeButton(getString(R.string.negative_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { + server.setMayReconnect(false); + reconnectDialogActive = false; dialog.cancel(); } }); diff --git a/application/src/org/yaaic/activity/ServersActivity.java b/application/src/org/yaaic/activity/ServersActivity.java index cfcf38d..aa3e83d 100644 --- a/application/src/org/yaaic/activity/ServersActivity.java +++ b/application/src/org/yaaic/activity/ServersActivity.java @@ -175,7 +175,7 @@ public class ServersActivity extends ListActivity implements ServiceConnection, Intent intent = new Intent(this, ConversationActivity.class); - if (server.getStatus() == Status.DISCONNECTED) { + if (server.getStatus() == Status.DISCONNECTED && !server.mayReconnect()) { server.setStatus(Status.PRE_CONNECTING); intent.putExtra("connect", true); } @@ -220,6 +220,7 @@ public class ServersActivity extends ListActivity implements ServiceConnection, case 1: // Disconnect server.clearConversations(); server.setStatus(Status.DISCONNECTED); + server.setMayReconnect(false); binder.getService().getConnection(server.getId()).quitServer(); break; case 2: // Edit @@ -292,6 +293,7 @@ public class ServersActivity extends ListActivity implements ServiceConnection, for (Server server : mServers) { if (binder.getService().hasConnection(server.getId())) { server.setStatus(Status.DISCONNECTED); + server.setMayReconnect(false); binder.getService().getConnection(server.getId()).quitServer(); } } diff --git a/application/src/org/yaaic/irc/IRCConnection.java b/application/src/org/yaaic/irc/IRCConnection.java index 1330f73..e5940f9 100644 --- a/application/src/org/yaaic/irc/IRCConnection.java +++ b/application/src/org/yaaic/irc/IRCConnection.java @@ -140,6 +140,7 @@ public class IRCConnection extends PircBot public void onConnect() { server.setStatus(Status.CONNECTED); + server.setMayReconnect(true); service.sendBroadcast( Broadcast.createServerIntent(Broadcast.SERVER_UPDATE, server.getId()) @@ -372,7 +373,7 @@ public class IRCConnection extends PircBot @Override protected void onJoin(String target, String sender, String login, String hostname) { - if (sender.equalsIgnoreCase(getNick())) { + if (sender.equalsIgnoreCase(getNick()) && server.getConversation(target) == null) { // We joined a new channel Conversation conversation = new Channel(target); conversation.setHistorySize(service.getSettings().getHistorySize()); @@ -1132,7 +1133,6 @@ public class IRCConnection extends PircBot if (service.getSettings().isReconnectEnabled() && server.getStatus() != Status.DISCONNECTED) { setAutojoinChannels(server.getCurrentChannelNames()); - server.clearConversations(); server.setStatus(Status.CONNECTING); service.connect(server); } else { diff --git a/application/src/org/yaaic/irc/IRCService.java b/application/src/org/yaaic/irc/IRCService.java index 00e0d36..ea0892c 100644 --- a/application/src/org/yaaic/irc/IRCService.java +++ b/application/src/org/yaaic/irc/IRCService.java @@ -485,7 +485,7 @@ public class IRCService extends Service for (int i = 0; i < mSize; i++) { server = mServers.get(i); - if (server.isDisconnected()) { + if (server.isDisconnected() && !server.mayReconnect()) { int serverId = server.getId(); synchronized(this) { IRCConnection connection = connections.get(serverId); diff --git a/application/src/org/yaaic/model/Server.java b/application/src/org/yaaic/model/Server.java index 156ed0c..58eca98 100644 --- a/application/src/org/yaaic/model/Server.java +++ b/application/src/org/yaaic/model/Server.java @@ -51,6 +51,7 @@ public class Server private int status = Status.DISCONNECTED; private String selected = ""; private boolean isForeground = false; + private boolean mayReconnect = false; /** * Create a new server object @@ -443,4 +444,20 @@ public class Server { this.isForeground = isForeground; } + + /** + * Get whether a reconnect may be attempted if we're disconnected. + */ + public boolean mayReconnect() + { + return mayReconnect; + } + + /** + * Set whether a reconnect may be attempted if we're disconnected. + */ + public void setMayReconnect(boolean mayReconnect) + { + this.mayReconnect = mayReconnect; + } }