CryptoMessage v1.3.2版本的 MD5 值为:66c611ce56a11450659dc23697562928

以下内容为反编译后的 XMPPTCPConnection.java 源代码,内容仅作参考


package org.jivesoftware.smack.tcp;

import androidx.constraintlayout.widget.R$styleable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.NonzaCallback;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackFuture;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.compress.packet.Compress;
import org.jivesoftware.smack.compress.packet.Compressed;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.datatypes.UInt16;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.internal.SmackTlsContext;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Nonza;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StartTls;
import org.jivesoftware.smack.packet.TlsProceed;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.sasl.packet.SaslNonza;
import org.jivesoftware.smack.sm.SMUtils;
import org.jivesoftware.smack.sm.StreamManagementException;
import org.jivesoftware.smack.sm.packet.StreamManagement;
import org.jivesoftware.smack.sm.predicates.Predicate;
import org.jivesoftware.smack.sm.provider.ParseStreamManagement;
import org.jivesoftware.smack.tcp.rce.RemoteXmppTcpConnectionEndpoints;
import org.jivesoftware.smack.tcp.rce.Rfc6120TcpRemoteConnectionEndpoint;
import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown;
import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.CloseableUtil;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.Supplier;
import org.jivesoftware.smack.util.TLSUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smack.util.dns.SmackDaneVerifier;
import org.jivesoftware.smack.util.rce.RemoteConnectionException;
import org.jivesoftware.smack.xml.SmackXmlParser;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import org.jxmpp.stringprep.XmppStringprepException;
import org.minidns.dnsname.DnsName;

public class XMPPTCPConnection extends AbstractXMPPConnection {
    static final boolean $assertionsDisabled = false;
    private static final int QUEUE_SIZE = 500;
    private static BundleAndDeferCallback defaultBundleAndDeferCallback;
    private BundleAndDeferCallback bundleAndDeferCallback;
    private long clientHandledStanzasCount;
    private boolean compressSyncPoint;
    private final XMPPTCPConnectionConfiguration config;
    private boolean disconnectedButResumeable;
    protected final PacketReader packetReader;
    protected final PacketWriter packetWriter;
    private final Set<StanzaFilter> requestAckPredicates;
    private SSLSocket secureSocket;
    private long serverHandledStanzasCount;
    private int smClientMaxResumptionTime;
    private volatile boolean smEnabledSyncPoint;
    private volatile AbstractXMPPConnection.SyncPointState smResumedSyncPoint;
    private StreamManagement.Failed smResumptionFailed;
    private int smServerMaxResumptionTime;
    private String smSessionId;
    private boolean smWasEnabledAtLeastOnce;
    private Socket socket;
    private final Collection<StanzaListener> stanzaAcknowledgedListeners;
    private final Collection<StanzaListener> stanzaDroppedListeners;
    private final Map<String, StanzaListener> stanzaIdAcknowledgedListeners;
    private boolean streamFeaturesAfterAuthenticationReceived;
    private BlockingQueue<Stanza> unacknowledgedStanzas;
    private boolean useSm;
    private boolean useSmResumption;
    private static final Logger LOGGER = Logger.getLogger(XMPPTCPConnection.class.getName());
    private static boolean useSmDefault = true;
    private static boolean useSmResumptionDefault = true;

    public XMPPTCPConnection(XMPPTCPConnectionConfiguration xMPPTCPConnectionConfiguration) {
        super(xMPPTCPConnectionConfiguration);
        this.disconnectedButResumeable = $assertionsDisabled;
        this.packetWriter = new PacketWriter();
        this.packetReader = new PacketReader();
        this.bundleAndDeferCallback = defaultBundleAndDeferCallback;
        this.smClientMaxResumptionTime = -1;
        this.smServerMaxResumptionTime = -1;
        this.useSm = useSmDefault;
        this.useSmResumption = useSmResumptionDefault;
        this.serverHandledStanzasCount = 0L;
        this.clientHandledStanzasCount = 0L;
        this.smWasEnabledAtLeastOnce = $assertionsDisabled;
        this.stanzaAcknowledgedListeners = new ConcurrentLinkedQueue();
        this.stanzaDroppedListeners = new ConcurrentLinkedQueue();
        this.stanzaIdAcknowledgedListeners = new ConcurrentHashMap();
        this.requestAckPredicates = new LinkedHashSet();
        this.config = xMPPTCPConnectionConfiguration;
        addConnectionListener(new ConnectionListener() {
            @Override
            public void connectionClosedOnError(Exception exc) {
                if ((exc instanceof XMPPException.StreamErrorException) || (exc instanceof StreamManagementException)) {
                    XMPPTCPConnection.this.dropSmState();
                }
            }
        });
        buildNonzaCallback().listenFor(SaslNonza.Success.class, new NonzaCallback.NonzaListener() {
            @Override
            public final void accept(Nonza nonza) {
                XMPPTCPConnection.this.lambda$new$0((SaslNonza.Success) nonza);
            }
        }).install();
    }

    public void lambda$new$0(SaslNonza.Success success) throws IOException {
        resetParser();
    }

    public XMPPTCPConnection(CharSequence charSequence, String str) throws XmppStringprepException {
        this(XMPPTCPConnectionConfiguration.builder().setXmppAddressAndPassword(charSequence, str).build());
    }

    public XMPPTCPConnection(CharSequence charSequence, String str, String str2) throws XmppStringprepException {
        this(XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword(charSequence, str).setXmppDomain(JidCreate.domainBareFrom(str2)).build());
    }

    @Override
    protected void throwNotConnectedExceptionIfAppropriate() throws SmackException.NotConnectedException {
        PacketWriter packetWriter = this.packetWriter;
        if (packetWriter == null) {
            throw new SmackException.NotConnectedException();
        }
        packetWriter.throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
    }

    @Override
    protected void throwAlreadyConnectedExceptionIfAppropriate() throws SmackException.AlreadyConnectedException {
        if (isConnected() && !this.disconnectedButResumeable) {
            throw new SmackException.AlreadyConnectedException();
        }
    }

    @Override
    protected void throwAlreadyLoggedInExceptionIfAppropriate() throws SmackException.AlreadyLoggedInException {
        if (isAuthenticated() && !this.disconnectedButResumeable) {
            throw new SmackException.AlreadyLoggedInException();
        }
    }

    @Override
    public void afterSuccessfulLogin(boolean z) throws SmackException.NotConnectedException, InterruptedException {
        this.disconnectedButResumeable = $assertionsDisabled;
        super.afterSuccessfulLogin(z);
    }

    @Override
    protected synchronized void loginInternal(String str, String str2, Resourcepart resourcepart) throws XMPPException, SmackException, IOException, InterruptedException {
        SSLSocket sSLSocket = this.secureSocket;
        SSLSession session = sSLSocket != null ? sSLSocket.getSession() : null;
        this.streamFeaturesAfterAuthenticationReceived = $assertionsDisabled;
        authenticate(str, str2, this.config.getAuthzid(), session);
        waitForConditionOrThrowConnectionException(new Supplier() {
            @Override
            public final Object get() {
                Boolean lambda$loginInternal$1;
                lambda$loginInternal$1 = XMPPTCPConnection.this.lambda$loginInternal$1();
                return lambda$loginInternal$1;
            }
        }, "compress features from server");
        maybeEnableCompression();
        this.smResumedSyncPoint = AbstractXMPPConnection.SyncPointState.initial;
        this.smResumptionFailed = null;
        if (isSmResumptionPossible()) {
            this.smResumedSyncPoint = AbstractXMPPConnection.SyncPointState.request_sent;
            sendNonza(new StreamManagement.Resume(this.clientHandledStanzasCount, this.smSessionId));
            waitForConditionOrConnectionException(new Supplier() {
                @Override
                public final Object get() {
                    Boolean lambda$loginInternal$2;
                    lambda$loginInternal$2 = XMPPTCPConnection.this.lambda$loginInternal$2();
                    return lambda$loginInternal$2;
                }
            }, "resume previous stream");
            if (this.smResumedSyncPoint == AbstractXMPPConnection.SyncPointState.successful) {
                afterSuccessfulLogin(true);
                return;
            }
            LOGGER.fine("Stream resumption failed, continuing with normal stream establishment process: " + this.smResumptionFailed);
        }
        this.smEnabledSyncPoint = $assertionsDisabled;
        LinkedList<Stanza> linkedList = new LinkedList();
        BlockingQueue<Stanza> blockingQueue = this.unacknowledgedStanzas;
        if (blockingQueue != null) {
            blockingQueue.drainTo(linkedList);
            dropSmState();
        }
        bindResourceAndEstablishSession(resourcepart);
        if (isSmAvailable() && this.useSm) {
            this.serverHandledStanzasCount = 0L;
            sendNonza(new StreamManagement.Enable(this.useSmResumption, this.smClientMaxResumptionTime));
            waitForConditionOrThrowConnectionException(new Supplier() {
                @Override
                public final Object get() {
                    Boolean lambda$loginInternal$3;
                    lambda$loginInternal$3 = XMPPTCPConnection.this.lambda$loginInternal$3();
                    return lambda$loginInternal$3;
                }
            }, "enabling stream mangement");
            synchronized (this.requestAckPredicates) {
                if (this.requestAckPredicates.isEmpty()) {
                    this.requestAckPredicates.add(Predicate.forMessagesOrAfter5Stanzas());
                }
            }
        }
        if (!this.stanzaDroppedListeners.isEmpty()) {
            for (Stanza stanza : linkedList) {
                Iterator<StanzaListener> it = this.stanzaDroppedListeners.iterator();
                while (it.hasNext()) {
                    try {
                        it.next().processStanza(stanza);
                    } catch (InterruptedException | SmackException.NotConnectedException | SmackException.NotLoggedInException e) {
                        LOGGER.log(Level.FINER, "StanzaDroppedListener received exception", e);
                    }
                }
            }
        } else {
            Iterator it2 = linkedList.iterator();
            while (it2.hasNext()) {
                sendStanzaInternal((Stanza) it2.next());
            }
        }
        afterSuccessfulLogin($assertionsDisabled);
    }

    public Boolean lambda$loginInternal$1() {
        return Boolean.valueOf(this.streamFeaturesAfterAuthenticationReceived);
    }

    public Boolean lambda$loginInternal$2() {
        return Boolean.valueOf((this.smResumedSyncPoint == AbstractXMPPConnection.SyncPointState.successful || this.smResumptionFailed != null) ? true : $assertionsDisabled);
    }

    public Boolean lambda$loginInternal$3() {
        return Boolean.valueOf(this.smEnabledSyncPoint);
    }

    @Override
    public boolean isSecureConnection() {
        if (this.secureSocket != null) {
            return true;
        }
        return $assertionsDisabled;
    }

    @Override
    protected void shutdown() {
        if (isSmEnabled()) {
            try {
                sendSmAcknowledgementInternal();
            } catch (InterruptedException | SmackException.NotConnectedException e) {
                LOGGER.log(Level.FINE, "Can not send final SM ack as connection is not connected", e);
            }
        }
        shutdown($assertionsDisabled);
    }

    @Override
    public synchronized void instantShutdown() {
        shutdown(true);
    }

    private void shutdown(boolean z) {
        if (!this.packetWriter.done()) {
            Logger logger = LOGGER;
            logger.finer(this.packetWriter.threadName + " shutdown()");
            this.packetWriter.shutdown(z);
            logger.finer(this.packetWriter.threadName + " shutdown() returned");
            if (!z) {
                waitForClosingStreamTagFromServer();
            }
        }
        Logger logger2 = LOGGER;
        logger2.finer(this.packetReader.threadName + " shutdown()");
        this.packetReader.shutdown();
        logger2.finer(this.packetReader.threadName + " shutdown() returned");
        CloseableUtil.maybeClose(this.socket, logger2);
        setWasAuthenticated();
        try {
            if (!waitFor(new Supplier() {
                @Override
                public final Object get() {
                    Boolean lambda$shutdown$4;
                    lambda$shutdown$4 = XMPPTCPConnection.this.lambda$shutdown$4();
                    return lambda$shutdown$4;
                }
            })) {
                logger2.severe("Reader and/or writer threads did not terminate timely. Writer running: " + this.packetWriter.running + ", Reader running: " + this.packetReader.running);
            } else {
                logger2.fine("Reader and writer threads terminated");
            }
        } catch (InterruptedException e) {
            LOGGER.log(Level.FINE, "Interrupted while waiting for reader and writer threads to terminate", (Throwable) e);
        }
        if (this.disconnectedButResumeable) {
            return;
        }
        if (z) {
            boolean isSmResumptionPossible = isSmResumptionPossible();
            this.disconnectedButResumeable = isSmResumptionPossible;
            if (!isSmResumptionPossible) {
                this.smSessionId = null;
            }
        } else {
            this.disconnectedButResumeable = $assertionsDisabled;
            dropSmState();
        }
        this.authenticated = $assertionsDisabled;
        this.connected = $assertionsDisabled;
        this.secureSocket = null;
        this.reader = null;
        this.writer = null;
        initState();
    }

    public Boolean lambda$shutdown$4() {
        return Boolean.valueOf((this.packetWriter.running || this.packetReader.running) ? $assertionsDisabled : true);
    }

    @Override
    public void sendNonza(Nonza nonza) throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(nonza);
    }

    @Override
    protected void sendStanzaInternal(Stanza stanza) throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(stanza);
        if (isSmEnabled()) {
            Iterator<StanzaFilter> it = this.requestAckPredicates.iterator();
            while (it.hasNext()) {
                if (it.next().accept(stanza)) {
                    requestSmAcknowledgementInternal();
                    return;
                }
            }
        }
    }

    private void connectUsingConfiguration() throws SmackException.ConnectionException, IOException, InterruptedException {
        RemoteXmppTcpConnectionEndpoints.Result<Rfc6120TcpRemoteConnectionEndpoint> result;
        ProxyInfo proxyInfo;
        Iterator<Rfc6120TcpRemoteConnectionEndpoint> it;
        RemoteXmppTcpConnectionEndpoints.Result<Rfc6120TcpRemoteConnectionEndpoint> lookup = RemoteXmppTcpConnectionEndpoints.lookup(this.config);
        ArrayList arrayList = new ArrayList();
        SocketFactory socketFactory = this.config.getSocketFactory();
        ProxyInfo proxyInfo2 = this.config.getProxyInfo();
        int connectTimeout = this.config.getConnectTimeout();
        if (socketFactory == null) {
            socketFactory = SocketFactory.getDefault();
        }
        SocketFactory socketFactory2 = socketFactory;
        Iterator<Rfc6120TcpRemoteConnectionEndpoint> it2 = lookup.discoveredRemoteConnectionEndpoints.iterator();
        while (it2.hasNext()) {
            Rfc6120TcpRemoteConnectionEndpoint next = it2.next();
            String charSequence = next.getHost().toString();
            UInt16 port = next.getPort();
            int intValue = port.intValue();
            if (proxyInfo2 == null) {
                Iterator<? extends InetAddress> it3 = next.getInetAddresses().iterator();
                while (true) {
                    if (!it3.hasNext()) {
                        result = lookup;
                        proxyInfo = proxyInfo2;
                        it = it2;
                        break;
                    }
                    SmackFuture.SocketFuture socketFuture = new SmackFuture.SocketFuture(socketFactory2);
                    InetAddress next2 = it3.next();
                    InetSocketAddress inetSocketAddress = new InetSocketAddress(next2, intValue);
                    it = it2;
                    Logger logger = LOGGER;
                    result = lookup;
                    StringBuilder sb = new StringBuilder();
                    proxyInfo = proxyInfo2;
                    sb.append("Trying to establish TCP connection to ");
                    sb.append(inetSocketAddress);
                    logger.finer(sb.toString());
                    socketFuture.connectAsync(inetSocketAddress, connectTimeout);
                    try {
                        this.socket = socketFuture.getOrThrow();
                        logger.finer("Established TCP connection to " + inetSocketAddress);
                        this.host = charSequence;
                        this.port = port;
                        return;
                    } catch (IOException e) {
                        arrayList.add(new RemoteConnectionException(next, next2, e));
                        if (it3.hasNext()) {
                            it2 = it;
                            lookup = result;
                            proxyInfo2 = proxyInfo;
                        }
                    }
                }
            } else {
                result = lookup;
                proxyInfo = proxyInfo2;
                it = it2;
                this.socket = socketFactory2.createSocket();
                StringUtils.requireNotNullNorEmpty(charSequence, "Host of endpoint " + next + " must not be null when using a Proxy");
                String str = charSequence + " at port " + intValue;
                Logger logger2 = LOGGER;
                logger2.finer("Trying to establish TCP connection via Proxy to " + str);
                try {
                    proxyInfo.getProxySocketConnection().connect(this.socket, charSequence, intValue, connectTimeout);
                    logger2.finer("Established TCP connection to " + str);
                    this.host = charSequence;
                    this.port = port;
                    return;
                } catch (IOException e2) {
                    CloseableUtil.maybeClose(this.socket, LOGGER);
                    arrayList.add(new RemoteConnectionException(next, null, e2));
                }
            }
            it2 = it;
            lookup = result;
            proxyInfo2 = proxyInfo;
        }
        throw SmackException.EndpointConnectionException.from(lookup.lookupFailures, arrayList);
    }

    private void initConnection() throws IOException, InterruptedException {
        this.compressionHandler = null;
        initReaderAndWriter();
        this.packetWriter.init();
        this.packetReader.init();
    }

    public void initReaderAndWriter() throws IOException {
        InputStream inputStream = this.socket.getInputStream();
        OutputStream outputStream = this.socket.getOutputStream();
        XMPPInputOutputStream xMPPInputOutputStream = this.compressionHandler;
        if (xMPPInputOutputStream != null) {
            inputStream = xMPPInputOutputStream.getInputStream(inputStream);
            outputStream = this.compressionHandler.getOutputStream(outputStream);
        }
        this.writer = new OutputStreamWriter(outputStream, "UTF-8");
        this.reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        initDebugger();
    }

    public void proceedTLSReceived() throws IOException, SmackException.SecurityNotPossibleException, CertificateException {
        String obj;
        SmackTlsContext smackTlsContext = getSmackTlsContext();
        Socket socket = this.socket;
        Socket createSocket = smackTlsContext.sslContext.getSocketFactory().createSocket(socket, this.config.getXMPPServiceDomain().toString(), socket.getPort(), true);
        this.socket = createSocket;
        SSLSocket sSLSocket = (SSLSocket) createSocket;
        TLSUtils.setEnabledProtocolsAndCiphers(sSLSocket, this.config.getEnabledSSLProtocols(), this.config.getEnabledSSLCiphers());
        initReaderAndWriter();
        sSLSocket.startHandshake();
        SmackDaneVerifier smackDaneVerifier = smackTlsContext.daneVerifier;
        if (smackDaneVerifier != null) {
            smackDaneVerifier.finish(sSLSocket.getSession());
        }
        HostnameVerifier hostnameVerifier = getConfiguration().getHostnameVerifier();
        if (hostnameVerifier == null) {
            throw new IllegalStateException("No HostnameVerifier set. Use connectionConfiguration.setHostnameVerifier() to configure.");
        }
        DnsName xmppServiceDomainAsDnsNameIfPossible = getConfiguration().getXmppServiceDomainAsDnsNameIfPossible();
        if (xmppServiceDomainAsDnsNameIfPossible != null) {
            obj = xmppServiceDomainAsDnsNameIfPossible.ace;
        } else {
            LOGGER.log(Level.WARNING, "XMPP service domain name '" + ((Object) getXMPPServiceDomain()) + "' can not be represented as DNS name. TLS X.509 certificate validiation may fail.");
            obj = getXMPPServiceDomain().toString();
        }
        if (!hostnameVerifier.verify(obj, sSLSocket.getSession())) {
            throw new CertificateException("Hostname verification of certificate failed. Certificate does not authenticate " + ((Object) getXMPPServiceDomain()));
        }
        this.secureSocket = sSLSocket;
    }

    private static XMPPInputOutputStream maybeGetCompressionHandler(Compress.Feature feature) {
        for (XMPPInputOutputStream xMPPInputOutputStream : SmackConfiguration.getCompressionHandlers()) {
            if (feature.getMethods().contains(xMPPInputOutputStream.getCompressionMethod())) {
                return xMPPInputOutputStream;
            }
        }
        return null;
    }

    @Override
    public boolean isUsingCompression() {
        if (this.compressionHandler == null || !this.compressSyncPoint) {
            return $assertionsDisabled;
        }
        return true;
    }

    private void maybeEnableCompression() throws SmackException, InterruptedException, XMPPException {
        Compress.Feature feature;
        if (this.config.isCompressionEnabled() && (feature = (Compress.Feature) getFeature(Compress.Feature.class)) != null) {
            XMPPInputOutputStream maybeGetCompressionHandler = maybeGetCompressionHandler(feature);
            this.compressionHandler = maybeGetCompressionHandler;
            if (maybeGetCompressionHandler != null) {
                this.compressSyncPoint = $assertionsDisabled;
                sendNonza(new Compress(maybeGetCompressionHandler.getCompressionMethod()));
                waitForConditionOrThrowConnectionException(new Supplier() {
                    @Override
                    public final Object get() {
                        Boolean lambda$maybeEnableCompression$5;
                        lambda$maybeEnableCompression$5 = XMPPTCPConnection.this.lambda$maybeEnableCompression$5();
                        return lambda$maybeEnableCompression$5;
                    }
                }, "establishing stream compression");
                return;
            }
            LOGGER.warning("Could not enable compression because no matching handler/method pair was found");
        }
    }

    public Boolean lambda$maybeEnableCompression$5() {
        return Boolean.valueOf(this.compressSyncPoint);
    }

    @Override
    protected void connectInternal() throws SmackException, IOException, XMPPException, InterruptedException {
        connectUsingConfiguration();
        this.connected = true;
        initConnection();
        waitForConditionOrThrowConnectionException(new Supplier() {
            @Override
            public final Object get() {
                Boolean lambda$connectInternal$6;
                lambda$connectInternal$6 = XMPPTCPConnection.this.lambda$connectInternal$6();
                return lambda$connectInternal$6;
            }
        }, "establishing TLS");
        waitForConditionOrThrowConnectionException(new Supplier() {
            @Override
            public final Object get() {
                Boolean lambda$connectInternal$7;
                lambda$connectInternal$7 = XMPPTCPConnection.this.lambda$connectInternal$7();
                return lambda$connectInternal$7;
            }
        }, "SASL mechanisms stream feature from server");
    }

    public Boolean lambda$connectInternal$6() {
        return Boolean.valueOf(this.tlsHandled);
    }

    public Boolean lambda$connectInternal$7() {
        return Boolean.valueOf(this.saslFeatureReceived);
    }

    protected void setWriter(Writer writer) {
        this.writer = writer;
    }

    @Override
    protected void afterFeaturesReceived() throws SmackException.NotConnectedException, InterruptedException, SmackException.SecurityRequiredByServerException {
        StartTls startTls = (StartTls) getFeature(StartTls.class);
        if (startTls != null) {
            if (startTls.required() && this.config.getSecurityMode() == ConnectionConfiguration.SecurityMode.disabled) {
                SmackException.SecurityRequiredByServerException securityRequiredByServerException = new SmackException.SecurityRequiredByServerException();
                this.currentSmackException = securityRequiredByServerException;
                notifyWaitingThreads();
                throw securityRequiredByServerException;
            }
            if (this.config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
                sendNonza(new StartTls());
            } else {
                this.tlsHandled = true;
                notifyWaitingThreads();
            }
        } else {
            this.tlsHandled = true;
            notifyWaitingThreads();
        }
        if (isSaslAuthenticated()) {
            this.streamFeaturesAfterAuthenticationReceived = true;
            notifyWaitingThreads();
        }
    }

    private void resetParser() throws IOException {
        try {
            this.packetReader.parser = SmackXmlParser.newXmlParser(this.reader);
        } catch (XmlPullParserException e) {
            throw new IOException(e);
        }
    }

    public void openStreamAndResetParser() throws IOException, SmackException.NotConnectedException, InterruptedException {
        sendStreamOpen();
        resetParser();
    }

    public class PacketReader {
        private volatile boolean done;
        XmlPullParser parser;
        private boolean running;
        private final String threadName;

        protected PacketReader() {
            this.threadName = "Smack Reader (" + XMPPTCPConnection.this.getConnectionCounter() + ')';
        }

        void init() {
            this.done = XMPPTCPConnection.$assertionsDisabled;
            this.running = true;
            Async.go(new Runnable() {
                @Override
                public void run() {
                    XMPPTCPConnection.LOGGER.finer(PacketReader.this.threadName + " start");
                    try {
                        PacketReader.this.parsePackets();
                    } finally {
                        XMPPTCPConnection.LOGGER.finer(PacketReader.this.threadName + " exit");
                        PacketReader.this.running = XMPPTCPConnection.$assertionsDisabled;
                        XMPPTCPConnection.this.notifyWaitingThreads();
                    }
                }
            }, this.threadName);
        }

        void shutdown() {
            this.done = true;
        }

        public void parsePackets() {
            try {
                XMPPTCPConnection.this.openStreamAndResetParser();
                XmlPullParser.Event eventType = this.parser.getEventType();
                while (!this.done) {
                    int i = AnonymousClass4.$SwitchMap$org$jivesoftware$smack$xml$XmlPullParser$Event[eventType.ordinal()];
                    char c = 3;
                    if (i == 1) {
                        String name = this.parser.getName();
                        char c2 = 65535;
                        switch (name.hashCode()) {
                            case -1609594047:
                                if (name.equals(StreamManagement.Enabled.ELEMENT)) {
                                    c = '\t';
                                    break;
                                }
                                break;
                            case -1281977283:
                                if (name.equals(StreamManagement.Failed.ELEMENT)) {
                                    c = '\n';
                                    break;
                                }
                                break;
                            case -1276666629:
                                if (name.equals(Presence.ELEMENT)) {
                                    c = 2;
                                    break;
                                }
                                break;
                            case -1086574198:
                                if (name.equals("failure")) {
                                    c = 7;
                                    break;
                                }
                                break;
                            case -891990144:
                                if (name.equals("stream")) {
                                    break;
                                }
                                break;
                            case -369449087:
                                if (name.equals(Compressed.ELEMENT)) {
                                    c = '\b';
                                    break;
                                }
                                break;
                            case -309519186:
                                if (name.equals(TlsProceed.ELEMENT)) {
                                    c = 6;
                                    break;
                                }
                                break;
                            case -290659267:
                                if (name.equals("features")) {
                                    c = 5;
                                    break;
                                }
                                break;
                            case R$styleable.Constraint_layout_goneMarginEnd:
                                if (name.equals("a")) {
                                    c = '\f';
                                    break;
                                }
                                break;
                            case 114:
                                if (name.equals(StreamManagement.AckRequest.ELEMENT)) {
                                    c = '\r';
                                    break;
                                }
                                break;
                            case 3368:
                                if (name.equals(IQ.IQ_ELEMENT)) {
                                    c = 1;
                                    break;
                                }
                                break;
                            case 96784904:
                                if (name.equals("error")) {
                                    c = 4;
                                    break;
                                }
                                break;
                            case 954925063:
                                if (name.equals("message")) {
                                    c = 0;
                                    break;
                                }
                                break;
                            case 1097547223:
                                if (name.equals(StreamManagement.Resumed.ELEMENT)) {
                                    c = 11;
                                    break;
                                }
                                break;
                        }
                        c = 65535;
                        switch (c) {
                            case 0:
                            case 1:
                            case 2:
                                try {
                                    XMPPTCPConnection.this.parseAndProcessStanza(this.parser);
                                    XMPPTCPConnection xMPPTCPConnection = XMPPTCPConnection.this;
                                    xMPPTCPConnection.clientHandledStanzasCount = SMUtils.incrementHeight(xMPPTCPConnection.clientHandledStanzasCount);
                                    break;
                                } catch (Throwable th) {
                                    XMPPTCPConnection xMPPTCPConnection2 = XMPPTCPConnection.this;
                                    xMPPTCPConnection2.clientHandledStanzasCount = SMUtils.incrementHeight(xMPPTCPConnection2.clientHandledStanzasCount);
                                    throw th;
                                }
                            case 3:
                                XMPPTCPConnection.this.onStreamOpen(this.parser);
                                break;
                            case 4:
                                throw new XMPPException.StreamErrorException(PacketParserUtils.parseStreamError(this.parser));
                            case 5:
                                XMPPTCPConnection.this.parseFeaturesAndNotify(this.parser);
                                break;
                            case 6:
                                XMPPTCPConnection.this.proceedTLSReceived();
                                XMPPTCPConnection.this.openStreamAndResetParser();
                                break;
                            case 7:
                                String namespace = this.parser.getNamespace(null);
                                int hashCode = namespace.hashCode();
                                if (hashCode == 919182852) {
                                    if (namespace.equals("urn:ietf:params:xml:ns:xmpp-tls")) {
                                        c2 = 0;
                                        break;
                                    }
                                } else if (hashCode == 2117926358 && namespace.equals("http://jabber.org/protocol/compress")) {
                                    c2 = 1;
                                    break;
                                }
                                throw new SmackException.SmackMessageException("TLS negotiation has failed");
                            case '\b':
                                XMPPTCPConnection.this.initReaderAndWriter();
                                XMPPTCPConnection.this.openStreamAndResetParser();
                                XMPPTCPConnection.this.compressSyncPoint = true;
                                XMPPTCPConnection.this.notifyWaitingThreads();
                                break;
                            case '\t':
                                StreamManagement.Enabled enabled = ParseStreamManagement.enabled(this.parser);
                                if (!enabled.isResumeSet()) {
                                    XMPPTCPConnection.this.smSessionId = null;
                                } else {
                                    XMPPTCPConnection.this.smSessionId = enabled.getId();
                                    if (StringUtils.isNullOrEmpty(XMPPTCPConnection.this.smSessionId)) {
                                        SmackException.SmackMessageException smackMessageException = new SmackException.SmackMessageException("Stream Management 'enabled' element with resume attribute but without session id received");
                                        XMPPTCPConnection.this.setCurrentConnectionExceptionAndNotify(smackMessageException);
                                        throw smackMessageException;
                                    }
                                    XMPPTCPConnection.this.smServerMaxResumptionTime = enabled.getMaxResumptionTime();
                                }
                                XMPPTCPConnection.this.clientHandledStanzasCount = 0L;
                                XMPPTCPConnection.this.smWasEnabledAtLeastOnce = true;
                                XMPPTCPConnection.this.smEnabledSyncPoint = true;
                                XMPPTCPConnection.this.notifyWaitingThreads();
                                break;
                            case '\n':
                                StreamManagement.Failed failed = ParseStreamManagement.failed(this.parser);
                                if (XMPPTCPConnection.this.smResumedSyncPoint == AbstractXMPPConnection.SyncPointState.request_sent) {
                                    XMPPTCPConnection.this.smResumptionFailed = failed;
                                    XMPPTCPConnection.this.notifyWaitingThreads();
                                    break;
                                } else {
                                    XMPPTCPConnection.this.setCurrentConnectionExceptionAndNotify(new XMPPException.FailedNonzaException(failed, failed.getStanzaErrorCondition()));
                                    break;
                                }
                            case 11:
                                StreamManagement.Resumed resumed = ParseStreamManagement.resumed(this.parser);
                                if (XMPPTCPConnection.this.smSessionId.equals(resumed.getPrevId())) {
                                    XMPPTCPConnection.this.smEnabledSyncPoint = true;
                                    XMPPTCPConnection.this.processHandledCount(resumed.getHandledCount());
                                    ArrayList arrayList = new ArrayList(XMPPTCPConnection.this.unacknowledgedStanzas.size());
                                    XMPPTCPConnection.this.unacknowledgedStanzas.drainTo(arrayList);
                                    Iterator it = arrayList.iterator();
                                    while (it.hasNext()) {
                                        XMPPTCPConnection.this.sendStanzaInternal((Stanza) it.next());
                                    }
                                    if (!arrayList.isEmpty()) {
                                        XMPPTCPConnection.this.requestSmAcknowledgementInternal();
                                    }
                                    XMPPTCPConnection.this.smResumedSyncPoint = AbstractXMPPConnection.SyncPointState.successful;
                                    XMPPTCPConnection.this.notifyWaitingThreads();
                                    break;
                                } else {
                                    throw new StreamManagementException.StreamIdDoesNotMatchException(XMPPTCPConnection.this.smSessionId, resumed.getPrevId());
                                }
                            case '\f':
                                XMPPTCPConnection.this.processHandledCount(ParseStreamManagement.ackAnswer(this.parser).getHandledCount());
                                break;
                            case '\r':
                                ParseStreamManagement.ackRequest(this.parser);
                                if (XMPPTCPConnection.this.smEnabledSyncPoint) {
                                    XMPPTCPConnection.this.sendSmAcknowledgementInternal();
                                    break;
                                } else {
                                    XMPPTCPConnection.LOGGER.warning("SM Ack Request received while SM is not enabled");
                                    break;
                                }
                            default:
                                XMPPTCPConnection.this.parseAndProcessNonza(this.parser);
                                break;
                        }
                    } else if (i != 2) {
                        if (i == 3) {
                            throw new SmackException.SmackMessageException("Parser got END_DOCUMENT event. This could happen e.g. if the server closed the connection without sending a closing stream element");
                        }
                    } else if (!"stream".equals(this.parser.getName())) {
                        continue;
                    } else if (!this.parser.getNamespace().equals("http://etherx.jabber.org/streams")) {
                        XMPPTCPConnection.LOGGER.warning(XMPPTCPConnection.this + " </stream> but different namespace " + this.parser.getNamespace());
                    } else {
                        boolean isShutdown = XMPPTCPConnection.this.packetWriter.queue.isShutdown();
                        ((AbstractXMPPConnection) XMPPTCPConnection.this).closingStreamReceived = true;
                        XMPPTCPConnection.this.notifyWaitingThreads();
                        if (isShutdown) {
                            return;
                        }
                        XMPPTCPConnection.LOGGER.info(XMPPTCPConnection.this + " received closing </stream> element. Server wants to terminate the connection, calling disconnect()");
                        AbstractXMPPConnection.ASYNC_BUT_ORDERED.performAsyncButOrdered(XMPPTCPConnection.this, new Runnable() {
                            @Override
                            public void run() {
                                XMPPTCPConnection.this.disconnect();
                            }
                        });
                    }
                    eventType = this.parser.next();
                }
            } catch (Exception e) {
                if (this.done) {
                    return;
                }
                this.running = XMPPTCPConnection.$assertionsDisabled;
                XMPPTCPConnection.this.notifyConnectionError(e);
            }
        }
    }

    public static class AnonymousClass4 {
        static final int[] $SwitchMap$org$jivesoftware$smack$xml$XmlPullParser$Event;

        static {
            int[] iArr = new int[XmlPullParser.Event.values().length];
            $SwitchMap$org$jivesoftware$smack$xml$XmlPullParser$Event = iArr;
            try {
                iArr[XmlPullParser.Event.START_ELEMENT.ordinal()] = 1;
            } catch (NoSuchFieldError unused) {
            }
            try {
                $SwitchMap$org$jivesoftware$smack$xml$XmlPullParser$Event[XmlPullParser.Event.END_ELEMENT.ordinal()] = 2;
            } catch (NoSuchFieldError unused2) {
            }
            try {
                $SwitchMap$org$jivesoftware$smack$xml$XmlPullParser$Event[XmlPullParser.Event.END_DOCUMENT.ordinal()] = 3;
            } catch (NoSuchFieldError unused3) {
            }
        }
    }

    public class PacketWriter {
        public static final int QUEUE_SIZE = 500;
        public static final int UNACKKNOWLEDGED_STANZAS_QUEUE_SIZE = 1024;
        public static final int UNACKKNOWLEDGED_STANZAS_QUEUE_SIZE_HIGH_WATER_MARK = 307;
        private volatile boolean instantShutdown;
        private boolean running;
        private boolean shouldBundleAndDefer;
        private final String threadName;
        private final ArrayBlockingQueueWithShutdown<Element> queue = new ArrayBlockingQueueWithShutdown<>(500, true);
        protected volatile Long shutdownTimestamp = null;

        protected PacketWriter() {
            this.threadName = "Smack Writer (" + XMPPTCPConnection.this.getConnectionCounter() + ')';
        }

        void init() {
            this.shutdownTimestamp = null;
            if (XMPPTCPConnection.this.unacknowledgedStanzas != null) {
                drainWriterQueueToUnacknowledgedStanzas();
            }
            this.queue.start();
            this.running = true;
            Async.go(new Runnable() {
                @Override
                public void run() {
                    XMPPTCPConnection.LOGGER.finer(PacketWriter.this.threadName + " start");
                    try {
                        PacketWriter.this.writePackets();
                    } finally {
                        XMPPTCPConnection.LOGGER.finer(PacketWriter.this.threadName + " exit");
                        PacketWriter.this.running = XMPPTCPConnection.$assertionsDisabled;
                        XMPPTCPConnection.this.notifyWaitingThreads();
                    }
                }
            }, this.threadName);
        }

        public boolean done() {
            if (this.shutdownTimestamp != null) {
                return true;
            }
            return XMPPTCPConnection.$assertionsDisabled;
        }

        protected void throwNotConnectedExceptionIfDoneAndResumptionNotPossible() throws SmackException.NotConnectedException {
            boolean isSmResumptionPossible;
            boolean done = done();
            if (!done || (isSmResumptionPossible = XMPPTCPConnection.this.isSmResumptionPossible())) {
                return;
            }
            throw new SmackException.NotConnectedException(XMPPTCPConnection.this, "done=" + done + " smResumptionPossible=" + isSmResumptionPossible);
        }

        protected void sendStreamElement(Element element) throws SmackException.NotConnectedException, InterruptedException {
            throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
            try {
                this.queue.put(element);
            } catch (InterruptedException e) {
                throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
                throw e;
            }
        }

        void shutdown(boolean z) {
            this.instantShutdown = z;
            this.queue.shutdown();
            this.shutdownTimestamp = Long.valueOf(System.currentTimeMillis());
        }

        private Element nextStreamElement() {
            if (this.queue.isEmpty()) {
                this.shouldBundleAndDefer = true;
            }
            try {
                return this.queue.take();
            } catch (InterruptedException e) {
                if (this.queue.isShutdown()) {
                    return null;
                }
                XMPPTCPConnection.LOGGER.log(Level.WARNING, "Writer thread was interrupted. Don't do that. Use disconnect() instead.", (Throwable) e);
                return null;
            }
        }

        public void writePackets() {
            while (!done()) {
                try {
                    Element nextStreamElement = nextStreamElement();
                    if (nextStreamElement != null) {
                        BundleAndDeferCallback bundleAndDeferCallback = XMPPTCPConnection.this.bundleAndDeferCallback;
                        if (bundleAndDeferCallback != null && XMPPTCPConnection.this.isAuthenticated() && this.shouldBundleAndDefer) {
                            this.shouldBundleAndDefer = XMPPTCPConnection.$assertionsDisabled;
                            AtomicBoolean atomicBoolean = new AtomicBoolean();
                            int bundleAndDeferMillis = bundleAndDeferCallback.getBundleAndDeferMillis(new BundleAndDefer(atomicBoolean));
                            if (bundleAndDeferMillis > 0) {
                                long j = bundleAndDeferMillis;
                                long currentTimeMillis = System.currentTimeMillis();
                                synchronized (atomicBoolean) {
                                    for (long j2 = j; !atomicBoolean.get() && j2 > 0; j2 = j - (System.currentTimeMillis() - currentTimeMillis)) {
                                        atomicBoolean.wait(j2);
                                    }
                                }
                            }
                        }
                        Stanza stanza = null;
                        if (nextStreamElement instanceof Stanza) {
                            stanza = (Stanza) nextStreamElement;
                        } else if (nextStreamElement instanceof StreamManagement.Enable) {
                            XMPPTCPConnection.this.unacknowledgedStanzas = new ArrayBlockingQueue(1024);
                        }
                        maybeAddToUnacknowledgedStanzas(stanza);
                        CharSequence xml = nextStreamElement.toXML(((AbstractXMPPConnection) XMPPTCPConnection.this).outgoingStreamXmlEnvironment);
                        if (xml instanceof XmlStringBuilder) {
                            try {
                                ((XmlStringBuilder) xml).write(((AbstractXMPPConnection) XMPPTCPConnection.this).writer, ((AbstractXMPPConnection) XMPPTCPConnection.this).outgoingStreamXmlEnvironment);
                            } catch (NullPointerException e) {
                                XMPPTCPConnection.LOGGER.log(Level.FINE, "NPE in XmlStringBuilder of " + nextStreamElement.getClass() + ": " + nextStreamElement, (Throwable) e);
                                throw e;
                            }
                        } else {
                            ((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write(xml.toString());
                        }
                        if (this.queue.isEmpty()) {
                            ((AbstractXMPPConnection) XMPPTCPConnection.this).writer.flush();
                        }
                        if (stanza != null) {
                            XMPPTCPConnection.this.firePacketSendingListeners(stanza);
                        }
                    }
                } catch (Exception e2) {
                    if (done() || this.queue.isShutdown()) {
                        XMPPTCPConnection.LOGGER.log(Level.FINE, "Ignoring Exception in writePackets()", (Throwable) e2);
                        return;
                    } else {
                        this.running = XMPPTCPConnection.$assertionsDisabled;
                        XMPPTCPConnection.this.notifyConnectionError(e2);
                        return;
                    }
                }
            }
            if (!this.instantShutdown) {
                while (!this.queue.isEmpty()) {
                    try {
                        Element remove = this.queue.remove();
                        if (remove instanceof Stanza) {
                            maybeAddToUnacknowledgedStanzas((Stanza) remove);
                        }
                        ((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write(remove.toXML().toString());
                    } catch (Exception e3) {
                        XMPPTCPConnection.LOGGER.log(Level.WARNING, "Exception flushing queue during shutdown, ignore and continue", (Throwable) e3);
                    }
                }
                try {
                    ((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write("</stream:stream>");
                    ((AbstractXMPPConnection) XMPPTCPConnection.this).writer.flush();
                } catch (Exception e4) {
                    XMPPTCPConnection.LOGGER.log(Level.WARNING, "Exception writing closing stream element", (Throwable) e4);
                }
                this.queue.clear();
                return;
            }
            if (this.instantShutdown && XMPPTCPConnection.this.isSmEnabled()) {
                drainWriterQueueToUnacknowledgedStanzas();
            }
        }

        private void drainWriterQueueToUnacknowledgedStanzas() {
            ArrayList arrayList = new ArrayList(this.queue.size());
            this.queue.drainTo(arrayList);
            for (int i = 0; i < arrayList.size(); i++) {
                Element element = (Element) arrayList.get(i);
                if (XMPPTCPConnection.this.unacknowledgedStanzas.remainingCapacity() == 0) {
                    XMPPTCPConnection.LOGGER.log(Level.WARNING, "Some stanzas may be lost as not all could be drained to the unacknowledged stanzas queue", (Throwable) StreamManagementException.UnacknowledgedQueueFullException.newWith(i, arrayList, XMPPTCPConnection.this.unacknowledgedStanzas));
                    return;
                } else {
                    if (element instanceof Stanza) {
                        XMPPTCPConnection.this.unacknowledgedStanzas.add((Stanza) element);
                    }
                }
            }
        }

        private void maybeAddToUnacknowledgedStanzas(Stanza stanza) throws IOException {
            if (XMPPTCPConnection.this.unacknowledgedStanzas == null || stanza == null) {
                return;
            }
            if (XMPPTCPConnection.this.unacknowledgedStanzas.size() == 307) {
                ((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write(StreamManagement.AckRequest.INSTANCE.toXML().toString());
            }
            try {
                XMPPTCPConnection.this.unacknowledgedStanzas.put(stanza);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    public static void setUseStreamManagementDefault(boolean z) {
        useSmDefault = z;
    }

    @Deprecated
    public static void setUseStreamManagementResumptiodDefault(boolean z) {
        setUseStreamManagementResumptionDefault(z);
    }

    public static void setUseStreamManagementResumptionDefault(boolean z) {
        if (z) {
            setUseStreamManagementDefault(z);
        }
        useSmResumptionDefault = z;
    }

    public void setUseStreamManagement(boolean z) {
        this.useSm = z;
    }

    public void setUseStreamManagementResumption(boolean z) {
        if (z) {
            setUseStreamManagement(z);
        }
        this.useSmResumption = z;
    }

    public void setPreferredResumptionTime(int i) {
        this.smClientMaxResumptionTime = i;
    }

    public boolean addRequestAckPredicate(StanzaFilter stanzaFilter) {
        boolean add;
        synchronized (this.requestAckPredicates) {
            add = this.requestAckPredicates.add(stanzaFilter);
        }
        return add;
    }

    public boolean removeRequestAckPredicate(StanzaFilter stanzaFilter) {
        boolean remove;
        synchronized (this.requestAckPredicates) {
            remove = this.requestAckPredicates.remove(stanzaFilter);
        }
        return remove;
    }

    public void removeAllRequestAckPredicates() {
        synchronized (this.requestAckPredicates) {
            this.requestAckPredicates.clear();
        }
    }

    public void requestSmAcknowledgement() throws StreamManagementException.StreamManagementNotEnabledException, SmackException.NotConnectedException, InterruptedException {
        if (!isSmEnabled()) {
            throw new StreamManagementException.StreamManagementNotEnabledException();
        }
        requestSmAcknowledgementInternal();
    }

    public void requestSmAcknowledgementInternal() throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.sendStreamElement(StreamManagement.AckRequest.INSTANCE);
    }

    public void sendSmAcknowledgement() throws StreamManagementException.StreamManagementNotEnabledException, SmackException.NotConnectedException, InterruptedException {
        if (!isSmEnabled()) {
            throw new StreamManagementException.StreamManagementNotEnabledException();
        }
        sendSmAcknowledgementInternal();
    }

    public void sendSmAcknowledgementInternal() throws SmackException.NotConnectedException, InterruptedException {
        this.packetWriter.queue.putIfNotShutdown(new StreamManagement.AckAnswer(this.clientHandledStanzasCount));
    }

    public void addStanzaAcknowledgedListener(StanzaListener stanzaListener) {
        this.stanzaAcknowledgedListeners.add(stanzaListener);
    }

    public boolean removeStanzaAcknowledgedListener(StanzaListener stanzaListener) {
        return this.stanzaAcknowledgedListeners.remove(stanzaListener);
    }

    public void removeAllStanzaAcknowledgedListeners() {
        this.stanzaAcknowledgedListeners.clear();
    }

    public void addStanzaDroppedListener(StanzaListener stanzaListener) {
        this.stanzaDroppedListeners.add(stanzaListener);
    }

    public boolean removeStanzaDroppedListener(StanzaListener stanzaListener) {
        return this.stanzaDroppedListeners.remove(stanzaListener);
    }

    public StanzaListener addStanzaIdAcknowledgedListener(final String str, StanzaListener stanzaListener) throws StreamManagementException.StreamManagementNotEnabledException {
        if (!this.smWasEnabledAtLeastOnce) {
            throw new StreamManagementException.StreamManagementNotEnabledException();
        }
        AbstractXMPPConnection.schedule(new Runnable() {
            @Override
            public void run() {
                XMPPTCPConnection.this.stanzaIdAcknowledgedListeners.remove(str);
            }
        }, Math.min(getMaxSmResumptionTime(), 10800), TimeUnit.SECONDS);
        return this.stanzaIdAcknowledgedListeners.put(str, stanzaListener);
    }

    public StanzaListener removeStanzaIdAcknowledgedListener(String str) {
        return this.stanzaIdAcknowledgedListeners.remove(str);
    }

    public void removeAllStanzaIdAcknowledgedListeners() {
        this.stanzaIdAcknowledgedListeners.clear();
    }

    public boolean isSmAvailable() {
        return hasFeature(StreamManagement.StreamManagementFeature.ELEMENT, StreamManagement.NAMESPACE);
    }

    public boolean isSmEnabled() {
        return this.smEnabledSyncPoint;
    }

    public boolean streamWasResumed() {
        if (this.smResumedSyncPoint == AbstractXMPPConnection.SyncPointState.successful) {
            return true;
        }
        return $assertionsDisabled;
    }

    public boolean isDisconnectedButSmResumptionPossible() {
        if (this.disconnectedButResumeable && isSmResumptionPossible()) {
            return true;
        }
        return $assertionsDisabled;
    }

    public boolean isSmResumptionPossible() {
        if (this.smSessionId == null) {
            return $assertionsDisabled;
        }
        Long l = this.packetWriter.shutdownTimestamp;
        if (l == null) {
            return true;
        }
        if (System.currentTimeMillis() > l.longValue() + (getMaxSmResumptionTime() * 1000)) {
            return $assertionsDisabled;
        }
        return true;
    }

    public void dropSmState() {
        this.smSessionId = null;
        this.unacknowledgedStanzas = null;
    }

    public int getMaxSmResumptionTime() {
        int i = this.smClientMaxResumptionTime;
        if (i <= 0) {
            i = Integer.MAX_VALUE;
        }
        int i2 = this.smServerMaxResumptionTime;
        return Math.min(i, i2 > 0 ? i2 : Integer.MAX_VALUE);
    }

    public void processHandledCount(long j) throws StreamManagementException.StreamManagementCounterError {
        long calculateDelta = SMUtils.calculateDelta(j, this.serverHandledStanzasCount);
        final ArrayList arrayList = new ArrayList(calculateDelta <= 2147483647L ? (int) calculateDelta : Integer.MAX_VALUE);
        for (long j2 = 0; j2 < calculateDelta; j2++) {
            Stanza poll = this.unacknowledgedStanzas.poll();
            if (poll == null) {
                throw new StreamManagementException.StreamManagementCounterError(j, this.serverHandledStanzasCount, calculateDelta, arrayList);
            }
            arrayList.add(poll);
        }
        boolean z = $assertionsDisabled;
        if (this.stanzaAcknowledgedListeners.isEmpty()) {
            Iterator it = arrayList.iterator();
            while (it.hasNext()) {
                String stanzaId = ((Stanza) it.next()).getStanzaId();
                if (stanzaId == null || !this.stanzaIdAcknowledgedListeners.containsKey(stanzaId)) {
                }
            }
            if (z) {
                AbstractXMPPConnection.asyncGo(new Runnable() {
                    @Override
                    public void run() {
                        StanzaListener stanzaListener;
                        for (Stanza stanza : arrayList) {
                            Iterator it2 = XMPPTCPConnection.this.stanzaAcknowledgedListeners.iterator();
                            while (it2.hasNext()) {
                                try {
                                    ((StanzaListener) it2.next()).processStanza(stanza);
                                } catch (InterruptedException | SmackException.NotConnectedException | SmackException.NotLoggedInException e) {
                                    XMPPTCPConnection.LOGGER.log(Level.FINER, "Received exception", e);
                                }
                            }
                            String stanzaId2 = stanza.getStanzaId();
                            if (!StringUtils.isNullOrEmpty(stanzaId2) && (stanzaListener = (StanzaListener) XMPPTCPConnection.this.stanzaIdAcknowledgedListeners.remove(stanzaId2)) != null) {
                                try {
                                    stanzaListener.processStanza(stanza);
                                } catch (InterruptedException | SmackException.NotConnectedException | SmackException.NotLoggedInException e2) {
                                    XMPPTCPConnection.LOGGER.log(Level.FINER, "Received exception", e2);
                                }
                            }
                        }
                    }
                });
            }
            this.serverHandledStanzasCount = j;
        }
        z = true;
        if (z) {
        }
        this.serverHandledStanzasCount = j;
    }

    public static void setDefaultBundleAndDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) {
        defaultBundleAndDeferCallback = bundleAndDeferCallback;
    }

    public void setBundleandDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) {
        this.bundleAndDeferCallback = bundleAndDeferCallback;
    }
}