diff --git a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java index 74129ff9d..f22789c78 100644 --- a/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java +++ b/lib/src/main/java/io/ably/lib/realtime/AblyRealtime.java @@ -290,7 +290,9 @@ protected void setChannelSerialsFromRecoverOption(Map serials) { protected Map getChannelSerials() { Map channelSerials = new HashMap<>(); for (Channel channel : this.channels.values()) { - channelSerials.put(channel.name, channel.properties.channelSerial); + if (channel.state == ChannelState.attached) { + channelSerials.put(channel.name, channel.properties.channelSerial); + } } return channelSerials; } diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index 818027a09..4ae7b353a 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -397,12 +397,12 @@ private void setAttached(ProtocolMessage message) { if(state == ChannelState.attached) { Log.v(TAG, String.format(Locale.ROOT, "Server initiated attach for channel %s", name)); if (!message.hasFlag(Flag.resumed)) { // RTL12 - presence.onAttached(message.hasFlag(Flag.has_presence), true); + presence.onAttached(message.hasFlag(Flag.has_presence)); emitUpdate(message.error, false); } } else { - presence.onAttached(message.hasFlag(Flag.has_presence), true); + presence.onAttached(message.hasFlag(Flag.has_presence)); setState(ChannelState.attached, message.error, message.hasFlag(Flag.resumed)); } } diff --git a/lib/src/main/java/io/ably/lib/realtime/Presence.java b/lib/src/main/java/io/ably/lib/realtime/Presence.java index b1c1dcb7d..bbfb3baf1 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Presence.java +++ b/lib/src/main/java/io/ably/lib/realtime/Presence.java @@ -589,6 +589,21 @@ public void enterClient(String clientId, Object data, CompletionListener listene updatePresence(new PresenceMessage(PresenceMessage.Action.enter, clientId, data), listener); } + private void enterClientWithId(String id, String clientId, Object data, CompletionListener listener) throws AblyException { + if(clientId == null) { + String errorMessage = String.format(Locale.ROOT, "Channel %s: unable to enter presence channel (null clientId specified)", channel.name); + Log.v(TAG, errorMessage); + if(listener != null) { + listener.onError(new ErrorInfo(errorMessage, 40000)); + return; + } + } + PresenceMessage presenceMsg = new PresenceMessage(PresenceMessage.Action.enter, clientId, data); + presenceMsg.id = id; + Log.v(TAG, "enterClient(); channel = " + channel.name + "; clientId = " + clientId); + updatePresence(presenceMsg, listener); + } + /** * Updates the data payload for a presence member using a given clientId. * Enables a single client to update presence on behalf of any number of clients using a single connection. @@ -887,7 +902,7 @@ private void failQueuedMessages(ErrorInfo reason) { * attach / detach ************************************/ - void onAttached(boolean hasPresence, boolean enterInternalPresenceMembers) { + void onAttached(boolean hasPresence) { /* Interrupt get() call => by unblocking presence.waitForSync()*/ synchronized (presence) { presence.notifyAll(); @@ -898,10 +913,7 @@ void onAttached(boolean hasPresence, boolean enterInternalPresenceMembers) { endSync(); } sendQueuedMessages(); // RTP5b - - if (enterInternalPresenceMembers) { // RTP17f - enterInternalMembers(); - } + enterInternalMembers(); // RTP17f } /** @@ -910,7 +922,7 @@ void onAttached(boolean hasPresence, boolean enterInternalPresenceMembers) { synchronized void enterInternalMembers() { for (final PresenceMessage item: internalPresence.values()) { try { - enterClient(item.clientId, item.data, new CompletionListener() { + enterClientWithId(item.id, item.clientId, item.data, new CompletionListener() { @Override public void onSuccess() { }