package de.thedevstack.conversationsplus.xmpp.disco; import android.util.Base64; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.crypto.axolotl.AxolotlService; import de.thedevstack.conversationsplus.xmpp.Xep; import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState; import de.tzur.conversations.Settings; /** */ public final class FeatureRegistry { public static final String IDENTITY_TYPE = "phone"; private static final String[] LEGACY_FEATURES = { "urn:xmpp:jingle:1", "urn:xmpp:jingle:apps:file-transfer:3", "urn:xmpp:jingle:transports:s5b:1", "urn:xmpp:jingle:transports:ibb:1", "http://jabber.org/protocol/muc", "jabber:x:conference", "http://jabber.org/protocol/caps", "http://jabber.org/protocol/disco#info", "urn:xmpp:avatar:metadata+notify", "http://jabber.org/protocol/nick+notify", ChatState.NAMESPACE, AxolotlService.PEP_DEVICE_LIST+"+notify"}; private static final String[] LEGACY_MESSAGE_CONFIRMATION_FEATURES = { "urn:xmpp:receipts" }; private final List features = new ArrayList<>(); private static final FeatureRegistry INSTANCE = new FeatureRegistry(); public static void add(String featureNamespace) { if (null != featureNamespace) { INSTANCE.features.add(featureNamespace); } } public static void remove(String featureNamespace) { if (null != featureNamespace && INSTANCE.features.contains(featureNamespace)) { INSTANCE.features.remove(featureNamespace); } } public static void add(Xep xep) { add(xep.featureNamespace()); } public static void remove(Xep xep) { remove(xep.featureNamespace()); } public static List getFeatures() { Collections.sort(INSTANCE.features); return INSTANCE.features; } public static String getCapHash() { StringBuilder s = new StringBuilder(); s.append("client/" + IDENTITY_TYPE + "//" + ConversationsPlusApplication.getNameAndVersion() + "<"); MessageDigest md; try { md = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { return null; } for (String feature : getFeatures()) { s.append(feature + "<"); } byte[] sha1 = md.digest(s.toString().getBytes()); return new String(Base64.encode(sha1, Base64.DEFAULT)); } private FeatureRegistry() { this.features.addAll(Arrays.asList(LEGACY_FEATURES)); if (Settings.CONFIRM_MESSAGE_RECEIVED) { this.features.addAll(Arrays.asList(LEGACY_MESSAGE_CONFIRMATION_FEATURES)); } } }