⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 impsconnection.java

📁 Android平台上即时通讯聊天工具源代码。 支持手机聊天。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007-2008 Esmertec AG. * Copyright (C) 2007-2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.im.imps;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import com.android.im.engine.ChatGroupManager;import com.android.im.engine.ChatSessionManager;import com.android.im.engine.Contact;import com.android.im.engine.ContactListManager;import com.android.im.engine.ImConnection;import com.android.im.engine.ImErrorInfo;import com.android.im.engine.ImException;import com.android.im.engine.LoginInfo;import com.android.im.engine.Presence;import com.android.im.imps.ImpsConnectionConfig.CirMethod;import com.android.im.imps.ImpsConnectionConfig.TransportType;/** * An implementation of ImConnection of Wireless Village IMPS protocol. */public class ImpsConnection extends ImConnection {    ImpsConnectionConfig mConfig;    DataChannel mDataChannel;    private CirChannel mCirChannel;    private PrimitiveDispatcherThread mDispatcherThread;    ImpsSession mSession;    ImpsTransactionManager mTransactionManager;    private ImpsChatSessionManager mChatSessionManager;    private ImpsContactListManager mContactListManager;    private ImpsChatGroupManager   mChatGroupManager;    private boolean mReestablishing;    /**     * Constructs a new WVConnection with a WVConnectionConfig object.     *     * @param config the configuration.     * @throws ImException if there's an error in the configuration.     */    public ImpsConnection(ImpsConnectionConfig config) {        super();        mConfig = config;        mTransactionManager = new ImpsTransactionManager(this);        mChatSessionManager = new ImpsChatSessionManager(this);        mContactListManager = new ImpsContactListManager(this);        mChatGroupManager   = new ImpsChatGroupManager(this);    }    /**     * Gets the configuration of this connection.     *     * @return the configuration.     */    ImpsConnectionConfig getConfig() {        return mConfig;    }    synchronized void shutdownOnError(ImErrorInfo error) {        if(mState == DISCONNECTED) {            return;        }        if (mCirChannel != null) {            mCirChannel.shutdown();        }        if (mDispatcherThread != null) {            mDispatcherThread.shutdown();        }        if (mDataChannel != null) {            mDataChannel.shutdown();        }        if (mContactListManager != null && !mReestablishing) {            mContactListManager.reset();        }        setState(mReestablishing ? SUSPENDED: DISCONNECTED, error);        mReestablishing = false;    }    void shutdown(){        shutdownOnError(null);    }    @Override    public int getCapability() {        return CAPABILITY_GROUP_CHAT | CAPABILITY_SESSION_REESTABLISHMENT;    }    @Override    public void loginAsync(LoginInfo loginInfo) {        if (!checkAndSetState(DISCONNECTED)) {            return;        }        try {            mSession = new ImpsSession(this, loginInfo);        } catch (ImException e) {            setState(DISCONNECTED, e.getImError());            return;        }        doLogin();    }    @Override    public void reestablishSessionAsync(            HashMap<String, String> cookie) {        if (!checkAndSetState(SUSPENDED)) {            return;        }        mReestablishing = true;        try {            mSession = new ImpsSession(this, cookie);        } catch (ImException e) {            setState(DISCONNECTED, e.getImError());            return;        }        doLogin();    }    @Override    public void networkTypeChanged() {        if (mCirChannel != null) {            mCirChannel.reconnect();        }    }    private synchronized boolean checkAndSetState(int state) {        if(mState != state){            return false;        }        setState(LOGGING_IN, null);        return true;    }    private void doLogin() {        try {            initDataChannel();            mDataChannel.connect();        } catch (ImException e) {            ImErrorInfo error = e.getImError();            if(error == null){                error = new ImErrorInfo(ImErrorInfo.UNKNOWN_LOGIN_ERROR,                        e.getMessage());            }            shutdownOnError(error);            return;        }        mDispatcherThread = new PrimitiveDispatcherThread(mDataChannel);        mDispatcherThread.start();        LoginTransaction login = new LoginTransaction();        login.startAuthenticate();    }    @Override    public HashMap<String, String> getSessionContext() {        if(mState != LOGGED_IN) {            return null;        } else {            return mSession.getContext();        }    }    class LoginTransaction extends MultiPhaseTransaction {        LoginTransaction() {            // We're not passing completion to ImpsAsyncTransaction. Instead            // we'll handle the notification in LoginTransaction.            super(mTransactionManager);        }        public void startAuthenticate() {            Primitive login = buildBasicLoginReq();            if (mConfig.use4wayLogin()) {                // first login request of 4 way login                String[] supportedDigestSchema = mConfig.getPasswordDigest().getSupportedDigestSchema();                for (String element : supportedDigestSchema) {                    login.addElement(ImpsTags.DigestSchema, element);                }            } else {                // 2 way login                login.addElement(ImpsTags.Password, mSession.getPassword());            }            sendRequest(login);        }        @Override        public TransactionStatus processResponse(Primitive response) {            if (response.getElement(ImpsTags.SessionID) != null) {                // If server chooses authentication based on network, we might                // got the final Login-Response before the 2nd Login-Request.                String sessionId = response.getElementContents(ImpsTags.SessionID);                String keepAliveTime = response.getElementContents(ImpsTags.KeepAliveTime);                String capablityReqeust = response.getElementContents(ImpsTags.CapabilityRequest);                long keepAlive = ImpsUtils.parseLong(keepAliveTime,                        mConfig.getDefaultKeepAliveInterval());                // make sure we always have time to send keep-alive requests.                // see buildBasicLoginReq().                keepAlive -= 5;                mSession.setId(sessionId);                mSession.setKeepAliveTime(keepAlive);                mSession.setCapablityRequestRequired(ImpsUtils.isTrue(capablityReqeust));                onAuthenticated();                return TransactionStatus.TRANSACTION_COMPLETED;            } else {                return sendSecondLogin(response);            }        }        @Override        public TransactionStatus processResponseError(ImpsErrorInfo error) {            if (error.getCode() == ImpsConstants.STATUS_UNAUTHORIZED                    && error.getPrimitive() != null) {                if (mConfig.use4wayLogin()) {                    // Not really an error. Send the 2nd Login-Request.                    return sendSecondLogin(error.getPrimitive());                } else {                    // We have already sent password in 2way login, while OZ's                    // yahoo gateway server returns "401 - Further authorization                    // required" instead of "409 - Invalid password" if the                    // password only contains spaces.                    shutdownOnError(new ImErrorInfo(409, "Invalid password"));                    return TransactionStatus.TRANSACTION_COMPLETED;                }            } else if(error.getCode() == ImpsConstants.STATUS_COULD_NOT_RECOVER_SESSION) {                // The server could not recover the session, create a new                // session and try to login again.                LoginInfo loginInfo = mSession.getLoginInfo();                try {                    mSession = new ImpsSession(ImpsConnection.this, loginInfo);                } catch (ImException ignore) {                    // This shouldn't happen since we have tried to login with                    // the loginInfo                }                startAuthenticate();                return TransactionStatus.TRANSACTION_COMPLETED;            } else {                shutdownOnError(error);                return TransactionStatus.TRANSACTION_COMPLETED;            }        }        private TransactionStatus sendSecondLogin(Primitive res) {            try {                Primitive secondLogin = buildBasicLoginReq();                String nonce = res.getElementContents(ImpsTags.Nonce);                String digestSchema = res.getElementContents(ImpsTags.DigestSchema);                String digestBytes = mConfig.getPasswordDigest().digest(digestSchema, nonce,                        mSession.getPassword());                secondLogin.addElement(ImpsTags.DigestBytes, digestBytes);                sendRequest(secondLogin);                return TransactionStatus.TRANSACTION_CONTINUE;            } catch (ImException e) {                ImpsLog.logError(e);                shutdownOnError(new ImErrorInfo(ImErrorInfo.UNKNOWN_ERROR, e.toString()));                return TransactionStatus.TRANSACTION_COMPLETED;            }        }        private void onAuthenticated() {            if(mSession.isCapablityRequestRequired()) {                mSession.negotiateCapabilityAsync(new AsyncCompletion(){                    public void onComplete() {                        onCapabilityNegotiated();                    }                    public void onError(ImErrorInfo error) {                        shutdownOnError(error);                    }                });            } else {                onCapabilityNegotiated();            }        }        void onCapabilityNegotiated() {            mDataChannel.setServerMinPoll(mSession.getServerPollMin());            if(getConfig().getCirChannelBinding() != CirMethod.NONE) {                try {                    setupCIRChannel();                } catch (ImException e) {                    shutdownOnError(new ImErrorInfo(                            ImErrorInfo.UNSUPPORTED_CIR_CHANNEL, e.toString()));                    return;                }            }            mSession.negotiateServiceAsync(new AsyncCompletion(){                public void onComplete() {                    onServiceNegotiated();                }                public void onError(ImErrorInfo error) {                    shutdownOnError(error);                }            });        }        void onServiceNegotiated() {            mDataChannel.startKeepAlive(mSession.getKeepAliveTime());            retrieveUserPresenceAsync(new AsyncCompletion() {                public void onComplete() {                    setState(LOGGED_IN, null);                    if (mReestablishing) {                        ImpsContactListManager listMgr=  (ImpsContactListManager) getContactListManager();                        listMgr.subscribeToAllListAsync();                        mReestablishing = false;                    }                }                public void onError(ImErrorInfo error) {                    // Just continue. initUserPresenceAsync already made a                    // default mUserPresence for us.                    onComplete();                }            });        }    }    @Override    public void logoutAsync() {        setState(LOGGING_OUT, null);        // Shutdown the CIR channel first.        if(mCirChannel != null) {            mCirChannel.shutdown();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -