Smack-omemo rework #177 - Newly installed omemoDevice failed to setup omemo messaging chat with existing contacts

The method rebuildSessionWith() is actually working. Corruption of the swordfish identityKeyPair is actually caused by aTalk method storeOmemoIdentityKey(); which mistakenly uses userDevice instead of contactDevice in storeOmemoIdentityKey() method.

After the correction in storeOmemoIdentityKey(), the last reported problems experienced by Note-3 and Note-8 is resolved, and Note-3 and Note-8 are now able to exchange omemo messages without problem.

The tests also demonstrated that the implementation of
PEPListener buddyDeviceListUpdateListener()
in aTalk is a must to take care and reconstruct the missing buddies identityKeys. Otherwise the previous reported problem will remain unresolved and omemo messaging will not work in aTalk.

I have included below aTalk implementation for your reference; for your consideration to include in your omemoManager
private final PEPListener deviceListUpdateListener
if you deem necessary:

    /**
     * PEPListener to add new buddy omemoDevice identityKey to identities table
     * This is necessary otherwise newly installed client will always fail to communicate with
     * buddies whom have been setup earlier.
     */

    private PEPListener buddyDeviceListUpdateListener = new PEPListener()
    {
        @Override
        public void eventReceived(EntityBareJid from, EventElement event,
                org.jivesoftware.smack.packet.Message message)
        {
            // Our deviceList, so nothing more to do as it is handled in OmemoManager
            if ((from == null) || from.equals(mOmemoManager.getOwnJid())) {
                return;
            }

            for (ExtensionElement items : event.getExtensions()) {
                if (!(items instanceof ItemsExtension)) {
                    continue;
                }

                final OmemoDevice userDevice = mOmemoManager.getOwnDevice();
                for (ExtensionElement item : ((ItemsExtension) items).getItems()) {
                    if (!(item instanceof PayloadItem<?>)) {
                        continue;
                    }

                    PayloadItem<?> payloadItem = (PayloadItem<?>) item;
                    if (!(payloadItem.getPayload() instanceof OmemoDeviceListElement)) {
                        continue;
                    }

                    // Get the published Device List
                    OmemoDeviceListElement receivedDeviceList = (OmemoDeviceListElement) payloadItem.getPayload();
                    Set<Integer> deviceList = receivedDeviceList.getDeviceIds();
                    for (int deviceID : deviceList) {
                        final OmemoDevice contactDevice = new OmemoDevice(from.asBareJid(), deviceID);
                        IdentityKey preKey = null;
                        try {
                            preKey = (IdentityKey) mOmemoStore.loadOmemoIdentityKey(userDevice, contactDevice);
                        } catch (CorruptedOmemoKeyException e) {
                            preKey = null;
                        }
                        // Get the preKeys for missing buddy deviceID
                        if (preKey == null) {
                            aTalkApp.showToastMessage("Rebuild new session for missing: " + contactDevice);
                            try {
                                OmemoManager.getInstanceFor(mConnection).rebuildSessionWith(contactDevice);
                            } catch (InterruptedException | SmackException.NotConnectedException
                                    | SmackException.NoResponseException | CorruptedOmemoKeyException
                                    | CannotEstablishOmemoSessionException
                                    | SmackException.NotLoggedInException e) {
                                logger.error("Could not rebuild session with: " + contactDevice + " Exception: ", e);
                            }
                        }
                    }
                }
            }
        }
    };