Skip to content

Commit

Permalink
Fixing issues caused by Service clearing its state while there's mess…
Browse files Browse the repository at this point in the history
…ages requiring the state queued.
  • Loading branch information
Rantanen authored and pcgod committed Nov 19, 2010
1 parent b8eb66d commit 85e910b
Showing 1 changed file with 82 additions and 33 deletions.
115 changes: 82 additions & 33 deletions src/org/pcgod/mumbleclient/service/MumbleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ public MumbleService getService() {
}
}

private abstract class ProtocolMessage implements Runnable {
@Override
public final void run() {
if (state != MumbleConnectionHost.STATE_DISCONNECTED) {
process();
} else {
Log.w(
Globals.LOG_TAG,
"Ignoring message, Service is disconnected");
}
}

protected abstract void process();
}

public static final String ACTION_CONNECT = "mumbleclient.action.CONNECT";
public static final String INTENT_CHANNEL_LIST_UPDATE = "mumbleclient.intent.CHANNEL_LIST_UPDATE";
public static final String INTENT_CURRENT_CHANNEL_CHANGED = "mumbleclient.intent.CURRENT_CHANNEL_CHANGED";
Expand Down Expand Up @@ -94,9 +109,9 @@ public MumbleService getService() {
private final MumbleProtocolHost protocolHost = new MumbleProtocolHost() {
@Override
public void channelAdded(final Channel channel) {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
channels.add(channel);
sendBroadcast(INTENT_CHANNEL_LIST_UPDATE);
}
Expand All @@ -105,9 +120,9 @@ public void run() {

@Override
public void channelRemoved(final int channelId) {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).id == channelId) {
channels.remove(i);
Expand All @@ -121,9 +136,9 @@ public void run() {

@Override
public void channelUpdated(final Channel channel) {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
for (int i = 0; i < channels.size(); i++) {
if (channels.get(i).id == channel.id) {
channels.set(i, channel);
Expand All @@ -136,19 +151,19 @@ public void run() {
}

public void currentChannelChanged() {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
sendBroadcast(INTENT_CURRENT_CHANNEL_CHANGED);
}
});
}

@Override
public void currentUserUpdated() {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
if (!canSpeak() && isRecording()) {
setRecording(false);
}
Expand All @@ -159,17 +174,27 @@ public void run() {
}

public void messageReceived(final Message msg) {
messages.add(msg);
final Bundle b = new Bundle();
b.putSerializable(EXTRA_MESSAGE, msg);
sendBroadcast(INTENT_CHAT_TEXT_UPDATE, b);
handler.post(new ProtocolMessage() {
@Override
public void process() {
messages.add(msg);
final Bundle b = new Bundle();
b.putSerializable(EXTRA_MESSAGE, msg);
sendBroadcast(INTENT_CHAT_TEXT_UPDATE, b);
}
});
}

public void messageSent(final Message msg) {
messages.add(msg);
final Bundle b = new Bundle();
b.putSerializable(EXTRA_MESSAGE, msg);
sendBroadcast(INTENT_CHAT_TEXT_UPDATE, b);
handler.post(new ProtocolMessage() {
@Override
public void process() {
messages.add(msg);
final Bundle b = new Bundle();
b.putSerializable(EXTRA_MESSAGE, msg);
sendBroadcast(INTENT_CHAT_TEXT_UPDATE, b);
}
});
}

@Override
Expand All @@ -188,16 +213,16 @@ public void setSynchronized(final boolean synced) {
@Override
public void run() {
MumbleService.this.synced = synced;
broadcastState();
updateConnectionState();
}
});
}

@Override
public void userAdded(final User user) {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
users.add(user);
final Bundle b = new Bundle();
b.putSerializable(EXTRA_USER, user);
Expand All @@ -208,9 +233,9 @@ public void run() {

@Override
public void userRemoved(final int userId) {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
for (int i = 0; i < users.size(); i++) {
if (users.get(i).session == userId) {
final User user = users.remove(i);
Expand All @@ -230,9 +255,9 @@ public void run() {

@Override
public void userUpdated(final User user) {
handler.post(new Runnable() {
handler.post(new ProtocolMessage() {
@Override
public void run() {
public void process() {
for (int i = 0; i < users.size(); i++) {
if (users.get(i).session == user.session) {
users.set(i, user);
Expand Down Expand Up @@ -295,12 +320,10 @@ public void run() {
mNotification = null;
}

// Clear the user and channel collections.
users.clear();
channels.clear();
}
updateConnectionState();

broadcastState();
tryClear();
}
}
});
}
Expand Down Expand Up @@ -352,6 +375,7 @@ public void run() {

private final Object[] mStartForegroundArgs = new Object[2];
private final Object[] mStopForegroundArgs = new Object[1];
private boolean isBound = false;

public boolean canSpeak() {
return mProtocol.canSpeak;
Expand Down Expand Up @@ -476,6 +500,7 @@ public void joinChannel(final int channelId) {

@Override
public IBinder onBind(final Intent intent) {
isBound = true;
Log.i(Globals.LOG_TAG, "MumbleService: Bound");
return mBinder;
}
Expand Down Expand Up @@ -523,6 +548,13 @@ public int onStartCommand(
return handleCommand(intent);
}

@Override
public boolean onUnbind(final Intent intent) {
isBound = false;
tryClear();
return false;
}

public void sendChannelTextMessage(
final String message,
final Channel channel) {
Expand Down Expand Up @@ -562,8 +594,6 @@ private void assertConnected() {
}

private void broadcastState() {
resolveConnectionState();

final Bundle b = new Bundle();
b.putSerializable(EXTRA_CONNECTION_STATE, serviceState);
sendBroadcast(INTENT_CONNECTION_STATE_CHANGED);
Expand All @@ -572,7 +602,22 @@ private void broadcastState() {
serviceState.toString());
}

private void resolveConnectionState() {
/**
* Attempts to clear the stored data.
*
* Clears the data only when it doesn't affect the objects that depend on
* the service.
*/
private void tryClear() {
if (!isBound && serviceState == ConnectionState.Disconnected) {
users.clear();
channels.clear();
}
}

private void updateConnectionState() {
final ConnectionState oldState = serviceState;

switch (state) {
case MumbleConnectionHost.STATE_CONNECTING:
serviceState = ConnectionState.Connecting;
Expand All @@ -587,6 +632,10 @@ private void resolveConnectionState() {
default:
Assert.fail();
}

if (oldState != serviceState) {
broadcastState();
}
}

void sendBroadcast(final String action) {
Expand Down

0 comments on commit 85e910b

Please sign in to comment.