powered by Jive Software

Smack 4.4.0-alpha3: The listener #roomDestroyed() callback in method MultiUserChat #checkPresenceCode is an unreachable code

Per XEP-0045: Multi-User Chat section
10.9 Destroying a Room Destroying a Room

Server response to an IQ request for room destroy does not contain any status codes. See also aTalk actual debug log below:

However MultiUserChat#presenceListener for case unavailable: will proceed to perform checkPresenceCode() only if the mucUser.hasStatus() is true as one of the test conditions.
Hence the unreachable code as shown below

        // Create a listener for all presence updates.
        presenceListener = new StanzaListener() {
            @Override
            public void processStanza(final Stanza packet) {
.....
                        case unavailable:
                            occupantsMap.remove(from);
                            MUCUser mucUser = MUCUser.from(packet);
                            if (mucUser != null && mucUser.hasStatus()) {
                                // Fire events according to the received presence code
                                checkPresenceCode(
                                    mucUser.getStatus(),
                                    presence.getFrom().equals(myRoomJID),
                                    mucUser,
                                    from);
                            } else {
                                // An occupant has left the room
                                if (!isUserStatusModification) {
                                    for (ParticipantStatusListener listener : participantStatusListeners) {
                                        listener.left(from);
                                    }
                                }
                            }
                            break;
=========== unreachable code ===========
        // The room has been destroyed.
        if (mucUser.getDestroy() != null) {
            MultiUserChat alternateMUC = multiUserChatManager.getMultiUserChat(mucUser.getDestroy().getJid());
            for (UserStatusListener listener : userStatusListeners) {
                listener.roomDestroyed(alternateMUC, mucUser.getDestroy().getReason());
            }

            // Reset occupant information.
            occupantsMap.clear();
            myRoomJid = null;
            userHasLeft();
        }
============= aTalk debug log =============
2020-01-23 18:32:57.831 14807-14974/org.atalk.android D/SMACK: SENT (0): 
    <iq to='chatroom-te@conference.atalk.org' id='GRW8B-138' type='set'>
      <query xmlns='http://jabber.org/protocol/muc#owner'>
        <destroy>
          <reason>
            test
          </reason>
        </destroy>
      </query>
    </iq>
2020-01-23 18:32:57.905 14807-14975/org.atalk.android D/SMACK: RECV (0): 
    <presence to='swordfish@atalk.org/atalk' from='chatroom-te@conference.atalk.org' type='unavailable' id='14693659791595029012'/>
2020-01-23 18:32:57.954 14807-14975/org.atalk.android D/SMACK: RECV (0): 
    <presence to='swordfish@atalk.org/atalk' from='chatroom-te@conference.atalk.org/swordfish' type='unavailable'>
      <x xmlns='http://jabber.org/protocol/muc#user'>
        <destroy>
          <reason>
            test
          </reason>
        </destroy>
        <item role='none' affiliation='none'/>
      </x>
    </presence>
2020-01-23 18:32:57.984 14807-14975/org.atalk.android D/SMACK: RECV (0): 
    <iq xml:lang='en-GB' to='swordfish@atalk.org/atalk' from='chatroom-te@conference.atalk.org' type='result' id='GRW8B-138'/>

aTalk has implemented the below patch for the MultipUserChat class. Without the patch, the chatRoom status is not being updated and not in sync with the actual. Also the callback roomDestroyed() is not being executed.

listener.roomDestroyed(alternateMUC, mucUser.getDestroy().getReason()).

The below patch is only for smack 4.4.0-alpha3 snapshot release i.e. Smack-4.4.0-alpha3-20190916 currently used in aTalk.

MultiUserChat.patch (5.3 KB)

The patch also fixed the shortfalls as reported in: