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.
This commit is contained in:
Steven Luo 2011-06-29 01:19:02 -07:00 committed by Sebastian Kaspari
parent a69fafc4dd
commit e7651315df
5 changed files with 38 additions and 14 deletions

View File

@ -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();
}
});

View File

@ -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();
}
}

View File

@ -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 {

View File

@ -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);

View File

@ -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;
}
}