FileDocCategorySizeDatePackage
MailTransport.javaAPI DocAndroid 1.5 API10455Wed May 06 22:42:46 BST 2009com.android.email.mail.transport

MailTransport

public class MailTransport extends Object implements com.android.email.mail.Transport
This class implements the common aspects of "transport", one layer below the specific wire protocols such as POP3, IMAP, or SMTP.

Fields Summary
public static final int
SOCKET_CONNECT_TIMEOUT
public static final int
SOCKET_READ_TIMEOUT
private String
mDebugLabel
private String
mHost
private int
mPort
private String[]
mUserInfoParts
private int
mConnectionSecurity
private Socket
mSocket
private InputStream
mIn
private OutputStream
mOut
Constructors Summary
public MailTransport(String debugLabel)
Simple constructor for starting from scratch. Call setUri() and setSecurity() to complete the configuration.

param
debugLabel Label used for Log.d calls


                                
       
        super();
        mDebugLabel = debugLabel;
    
Methods Summary
public booleancanTrySslSecurity()

        return (mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED
                || mConnectionSecurity == CONNECTION_SECURITY_SSL_OPTIONAL);
    
public booleancanTryTlsSecurity()

        return (mConnectionSecurity == Transport.CONNECTION_SECURITY_TLS_OPTIONAL
                || mConnectionSecurity == Transport.CONNECTION_SECURITY_TLS_REQUIRED);
    
public voidclose()
Close the connection. MUST NOT return any exceptions - must be "best effort" and safe.

        try {
            mIn.close();
        } catch (Exception e) {
            // May fail if the connection is already closed.
        }
        try {
            mOut.close();
        } catch (Exception e) {
            // May fail if the connection is already closed.
        }
        try {
            mSocket.close();
        } catch (Exception e) {
            // May fail if the connection is already closed.
        }
        mIn = null;
        mOut = null;
        mSocket = null;
    
public java.lang.StringgetHost()

        return mHost;
    
public java.io.InputStreamgetInputStream()

        return mIn;
    
public java.io.OutputStreamgetOutputStream()

        return mOut;
    
public intgetPort()

        return mPort;
    
public intgetSecurity()

        return mConnectionSecurity;
    
public java.lang.String[]getUserInfoParts()

        return mUserInfoParts;
    
public booleanisOpen()

        return (mIn != null && mOut != null && 
                mSocket != null && mSocket.isConnected() && !mSocket.isClosed());
    
public com.android.email.mail.TransportnewInstanceWithConfiguration()
Get a new transport, using an existing one as a model. The new transport is configured as if setUri() and setSecurity() have been called, but not opened or connected in any way.

return
a new Transport ready to open()

        MailTransport newObject = new MailTransport(mDebugLabel);
        
        newObject.mDebugLabel = mDebugLabel;
        newObject.mHost = mHost;
        newObject.mPort = mPort;
        if (mUserInfoParts != null) {
            newObject.mUserInfoParts = mUserInfoParts.clone();
        }
        newObject.mConnectionSecurity = mConnectionSecurity;
        return newObject;
    
public voidopen()
Attempts to open a connection using the Uri supplied for connection parameters. Will attempt an SSL connection if indicated.

        if (Config.LOGD && Email.DEBUG) {
            Log.d(Email.LOG_TAG, "*** " + mDebugLabel + " open " + 
                    getHost() + ":" + String.valueOf(getPort()));
        }

        try {
            SocketAddress socketAddress = new InetSocketAddress(getHost(), getPort());
            if (canTrySslSecurity()) {
                SSLContext sslContext = SSLContext.getInstance("TLS");
                final boolean secure = getSecurity() == Transport.CONNECTION_SECURITY_SSL_REQUIRED;
                sslContext.init(null, new TrustManager[] {
                        TrustManagerFactory.get(getHost(), secure)
                }, new SecureRandom());
                mSocket = sslContext.getSocketFactory().createSocket();
            } else {
                mSocket = new Socket();
            }
            mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
            mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
            mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
            
        } catch (SSLException e) {
            if (Config.LOGD && Email.DEBUG) {
                Log.d(Email.LOG_TAG, e.toString());
            }
            throw new CertificateValidationException(e.getMessage(), e);
        } catch (GeneralSecurityException gse) {
            if (Config.LOGD && Email.DEBUG) {
                Log.d(Email.LOG_TAG, gse.toString());
            }
            throw new MessagingException(MessagingException.GENERAL_SECURITY, gse.toString());
        } catch (IOException ioe) {
            if (Config.LOGD && Email.DEBUG) {
                Log.d(Email.LOG_TAG, ioe.toString());
            }
            throw new MessagingException(MessagingException.IOERROR, ioe.toString());
        }
    
public java.lang.StringreadLine()
Reads a single line from the server, using either \r\n or \n as the delimiter. The delimiter char(s) are not included in the result.

        StringBuffer sb = new StringBuffer();
        InputStream in = getInputStream();
        int d;
        while ((d = in.read()) != -1) {
            if (((char)d) == '\r") {
                continue;
            } else if (((char)d) == '\n") {
                break;
            } else {
                sb.append((char)d);
            }
        }
        if (d == -1 && Config.LOGD && Email.DEBUG) {
            Log.d(Email.LOG_TAG, "End of stream reached while trying to read line.");
        }
        String ret = sb.toString();
        if (Config.LOGD) {
            if (Email.DEBUG) {
                Log.d(Email.LOG_TAG, "<<< " + ret);
            }
        }
        return ret;
    
public voidreopenTls()
Attempts to reopen a TLS connection using the Uri supplied for connection parameters. TODO should we explicitly close the old socket? This seems funky to abandon it.

        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            boolean secure = getSecurity() == CONNECTION_SECURITY_TLS_REQUIRED;
            sslContext.init(null, new TrustManager[] {
                    TrustManagerFactory.get(getHost(), secure)
            }, new SecureRandom());
            mSocket = sslContext.getSocketFactory().createSocket(mSocket, getHost(), getPort(),
                    true);
            mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
            mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
            mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);

        } catch (GeneralSecurityException gse) {
            if (Config.LOGD && Email.DEBUG) {
                Log.d(Email.LOG_TAG, gse.toString());
            }
            throw new MessagingException(MessagingException.GENERAL_SECURITY, gse.toString());
        } catch (IOException ioe) {
            if (Config.LOGD && Email.DEBUG) {
                Log.d(Email.LOG_TAG, ioe.toString());
            }
            throw new MessagingException(MessagingException.IOERROR, ioe.toString());
        }
    
public voidsetSecurity(int connectionSecurity)

        mConnectionSecurity = connectionSecurity;
    
public voidsetSoTimeout(int timeoutMilliseconds)
Set the socket timeout.

param
timeoutMilliseconds the read timeout value if greater than {@code 0}, or {@code 0} for an infinite timeout.

        mSocket.setSoTimeout(timeoutMilliseconds);
    
public voidsetUri(java.net.URI uri, int defaultPort)

        mHost = uri.getHost();

        mPort = defaultPort;
        if (uri.getPort() != -1) {
            mPort = uri.getPort();
        }

        if (uri.getUserInfo() != null) {
            mUserInfoParts = uri.getUserInfo().split(":", 2);
        }
        
    
public voidwriteLine(java.lang.String s, java.lang.String sensitiveReplacement)
Writes a single line to the server using \r\n termination.

        if (Config.LOGD && Email.DEBUG) {
            if (sensitiveReplacement != null && !Email.DEBUG_SENSITIVE) {
                Log.d(Email.LOG_TAG, ">>> " + sensitiveReplacement);
            } else {
                Log.d(Email.LOG_TAG, ">>> " + s);
            }
        }
        
        OutputStream out = getOutputStream();
        out.write(s.getBytes());
        out.write('\r");
        out.write('\n");
        out.flush();