diff --git a/android-stub/src/main/java/com/android/org/conscrypt/NativeCrypto.java b/android-stub/src/main/java/com/android/org/conscrypt/NativeCrypto.java
index 831dd17..851e27b 100644
--- a/android-stub/src/main/java/com/android/org/conscrypt/NativeCrypto.java
+++ b/android-stub/src/main/java/com/android/org/conscrypt/NativeCrypto.java
@@ -20,6 +20,7 @@
 import java.security.cert.CertificateException;
 import javax.net.ssl.SSLException;
 
+@SuppressWarnings("unused")
 final class NativeCrypto {
     public interface SSLHandshakeCallbacks {
         /**
diff --git a/android-stub/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java b/android-stub/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
index 079f89f..651d431 100644
--- a/android-stub/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
+++ b/android-stub/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
@@ -16,7 +16,7 @@
 
 package com.android.org.conscrypt;
 
-class SSLParametersImpl {
+final class SSLParametersImpl {
     public static SSLParametersImpl getDefault() {
         throw new RuntimeException("Stub!");
     }
diff --git a/android/proguard-rules.pro b/android/proguard-rules.pro
index c3bdd2c..3bc75b2 100644
--- a/android/proguard-rules.pro
+++ b/android/proguard-rules.pro
@@ -20,5 +20,7 @@
 -dontwarn dalvik.system.BlockGuard
 -dontwarn dalvik.system.BlockGuard$Policy
 -dontwarn dalvik.system.CloseGuard
+-dontwarn com.android.org.conscrypt.AbstractConscryptSocket
+-dontwarn com.android.org.conscrypt.ConscryptFileDescriptorSocket
 -dontwarn com.android.org.conscrypt.OpenSSLSocketImpl
 -dontwarn org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
diff --git a/android/src/main/java/org/conscrypt/KitKatPlatformOpenSSLSocketImplAdapter.java b/android/src/main/java/org/conscrypt/KitKatPlatformOpenSSLSocketImplAdapter.java
index 556b815..db7dc85 100644
--- a/android/src/main/java/org/conscrypt/KitKatPlatformOpenSSLSocketImplAdapter.java
+++ b/android/src/main/java/org/conscrypt/KitKatPlatformOpenSSLSocketImplAdapter.java
@@ -45,9 +45,9 @@
         extends com.android.org.conscrypt.OpenSSLSocketImpl {
 
 
-    private final org.conscrypt.OpenSSLSocketImpl delegate;
+    private final AbstractConscryptSocket delegate;
 
-    public KitKatPlatformOpenSSLSocketImplAdapter(org.conscrypt.OpenSSLSocketImpl delegate)
+    public KitKatPlatformOpenSSLSocketImplAdapter(AbstractConscryptSocket delegate)
             throws IOException {
         super(null);
         this.delegate = delegate;
diff --git a/android/src/main/java/org/conscrypt/Platform.java b/android/src/main/java/org/conscrypt/Platform.java
index e7663ae..be8eba6 100644
--- a/android/src/main/java/org/conscrypt/Platform.java
+++ b/android/src/main/java/org/conscrypt/Platform.java
@@ -82,9 +82,8 @@
         }
     }
 
-    public static FileDescriptor getFileDescriptorFromSSLSocket(
-            OpenSSLSocketImpl openSSLSocketImpl) {
-        return getFileDescriptor(openSSLSocketImpl);
+    public static FileDescriptor getFileDescriptorFromSSLSocket(AbstractConscryptSocket socket) {
+        return getFileDescriptor(socket);
     }
 
     public static String getCurveName(ECParameterSpec spec) {
@@ -195,7 +194,7 @@
     }
 
     public static void setSSLParameters(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket) {
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
         try {
             setSSLParametersOnImpl(params, impl);
 
@@ -260,7 +259,7 @@
     }
 
     public static void getSSLParameters(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket) {
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
         try {
             getSSLParametersFromImpl(params, impl);
 
@@ -276,7 +275,7 @@
 
     @TargetApi(24)
     private static void setParametersSniHostname(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket)
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket)
             throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         if (impl.getUseSni() && AddressUtils.isValidSniHostname(socket.getHostname())) {
             Method m_setServerNames = params.getClass().getMethod("setServerNames", List.class);
@@ -360,9 +359,9 @@
         return false;
     }
 
-    @SuppressLint("NewApi") // OpenSSLSocketImpl defines getHandshakeSession()
+    @SuppressLint("NewApi") // AbstractConscryptSocket defines getHandshakeSession()
     public static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain,
-            String authType, OpenSSLSocketImpl socket) throws CertificateException {
+            String authType, AbstractConscryptSocket socket) throws CertificateException {
         if (!checkTrusted("checkClientTrusted", tm, chain, authType, Socket.class, socket)
                 && !checkTrusted("checkClientTrusted", tm, chain, authType, String.class,
                            socket.getHandshakeSession().getPeerHost())) {
@@ -370,9 +369,9 @@
         }
     }
 
-    @SuppressLint("NewApi") // OpenSSLSocketImpl defines getHandshakeSession()
+    @SuppressLint("NewApi") // AbstractConscryptSocket defines getHandshakeSession()
     public static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain,
-            String authType, OpenSSLSocketImpl socket) throws CertificateException {
+            String authType, AbstractConscryptSocket socket) throws CertificateException {
         if (!checkTrusted("checkServerTrusted", tm, chain, authType, Socket.class, socket)
                 && !checkTrusted("checkServerTrusted", tm, chain, authType, String.class,
                            socket.getHandshakeSession().getPeerHost())) {
@@ -380,7 +379,7 @@
         }
     }
 
-    @SuppressLint("NewApi") // OpenSSLSocketImpl defines getHandshakeSession()
+    @SuppressLint("NewApi") // AbstractConscryptSocket defines getHandshakeSession()
     public static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain,
             String authType, ConscryptEngine engine) throws CertificateException {
         if (!checkTrusted("checkClientTrusted", tm, chain, authType, SSLEngine.class, engine)
@@ -390,7 +389,7 @@
         }
     }
 
-    @SuppressLint("NewApi") // OpenSSLSocketImpl defines getHandshakeSession()
+    @SuppressLint("NewApi") // AbstractConscryptSocket defines getHandshakeSession()
     public static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain,
             String authType, ConscryptEngine engine) throws CertificateException {
         if (!checkTrusted("checkServerTrusted", tm, chain, authType, SSLEngine.class, engine)
diff --git a/android/src/main/java/org/conscrypt/PreKitKatPlatformOpenSSLSocketImplAdapter.java b/android/src/main/java/org/conscrypt/PreKitKatPlatformOpenSSLSocketImplAdapter.java
index 1a89208..9353a91 100644
--- a/android/src/main/java/org/conscrypt/PreKitKatPlatformOpenSSLSocketImplAdapter.java
+++ b/android/src/main/java/org/conscrypt/PreKitKatPlatformOpenSSLSocketImplAdapter.java
@@ -45,9 +45,9 @@
         extends org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl {
 
 
-    private final org.conscrypt.OpenSSLSocketImpl delegate;
+    private final AbstractConscryptSocket delegate;
 
-    public PreKitKatPlatformOpenSSLSocketImplAdapter(org.conscrypt.OpenSSLSocketImpl delegate)
+    public PreKitKatPlatformOpenSSLSocketImplAdapter(AbstractConscryptSocket delegate)
             throws IOException {
         super(null);
         this.delegate = delegate;
diff --git a/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java b/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java
new file mode 100644
index 0000000..df6fbaa
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java
@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2017 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 org.conscrypt;
+
+import static org.conscrypt.Preconditions.checkArgument;
+import static org.conscrypt.Preconditions.checkNotNull;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SocketChannel;
+import java.security.PrivateKey;
+import java.util.ArrayList;
+import java.util.List;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * Abstract base class for all Conscrypt sockets that extends the basic {@link SSLSocket} API.
+ */
+abstract class AbstractConscryptSocket extends SSLSocket {
+    final Socket socket;
+    private final boolean autoClose;
+
+    /**
+     * The peer's DNS hostname if it was supplied during creation. Note that
+     * this may be a raw IP address, so it should be checked before use with
+     * extensions that don't use it like Server Name Indication (SNI).
+     */
+    private String peerHostname;
+
+    /**
+     * The peer's port if it was supplied during creation. Should only be set if
+     * {@link #peerHostname} is also set.
+     */
+    private final int peerPort;
+
+    private final PeerInfoProvider peerInfoProvider = new PeerInfoProvider() {
+        @Override
+        String getHostname() {
+            return AbstractConscryptSocket.this.getHostname();
+        }
+
+        @Override
+        String getHostnameOrIP() {
+            return AbstractConscryptSocket.this.getHostnameOrIP();
+        }
+
+        @Override
+        int getPort() {
+            return AbstractConscryptSocket.this.getPort();
+        }
+    };
+
+    private final List<HandshakeCompletedListener> listeners =
+            new ArrayList<HandshakeCompletedListener>(2);
+
+    /**
+     * Local cache of timeout to avoid getsockopt on every read and
+     * write for non-wrapped sockets. Note that this is not used when delegating
+     * to another socket.
+     */
+    private int readTimeoutMilliseconds;
+
+    AbstractConscryptSocket() throws IOException {
+        this.socket = this;
+        this.peerHostname = null;
+        this.peerPort = -1;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(String hostname, int port) throws IOException {
+        super(hostname, port);
+        this.socket = this;
+        this.peerHostname = hostname;
+        this.peerPort = port;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(InetAddress address, int port) throws IOException {
+        super(address, port);
+        this.socket = this;
+        this.peerHostname = null;
+        this.peerPort = -1;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(String hostname, int port, InetAddress clientAddress, int clientPort)
+            throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+        this.socket = this;
+        this.peerHostname = hostname;
+        this.peerPort = port;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(InetAddress address, int port, InetAddress clientAddress,
+            int clientPort) throws IOException {
+        super(address, port, clientAddress, clientPort);
+        this.socket = this;
+        this.peerHostname = null;
+        this.peerPort = -1;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(Socket socket, String hostname, int port, boolean autoClose)
+            throws IOException {
+        this.socket = checkNotNull(socket, "socket");
+        this.peerHostname = hostname;
+        this.peerPort = port;
+        this.autoClose = autoClose;
+    }
+
+    @Override
+    public final void connect(SocketAddress endpoint) throws IOException {
+        connect(endpoint, 0);
+    }
+
+    /**
+     * Try to extract the peer's hostname if it's available from the endpoint address.
+     */
+    @Override
+    public final void connect(SocketAddress endpoint, int timeout) throws IOException {
+        if (peerHostname == null && endpoint instanceof InetSocketAddress) {
+            peerHostname =
+                    Platform.getHostStringFromInetSocketAddress((InetSocketAddress) endpoint);
+        }
+
+        if (isDelegating()) {
+            socket.connect(endpoint, timeout);
+        } else {
+            super.connect(endpoint, timeout);
+        }
+    }
+
+    @Override
+    public void bind(SocketAddress bindpoint) throws IOException {
+        if (isDelegating()) {
+            socket.bind(bindpoint);
+        } else {
+            super.bind(bindpoint);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void close() throws IOException {
+        if (isDelegating()) {
+            if (autoClose && !socket.isClosed()) {
+                socket.close();
+            }
+        } else {
+            if (!super.isClosed()) {
+                super.close();
+            }
+        }
+    }
+
+    @Override
+    public InetAddress getInetAddress() {
+        if (isDelegating()) {
+            return socket.getInetAddress();
+        }
+        return super.getInetAddress();
+    }
+
+    @Override
+    public InetAddress getLocalAddress() {
+        if (isDelegating()) {
+            return socket.getLocalAddress();
+        }
+        return super.getLocalAddress();
+    }
+
+    @Override
+    public int getLocalPort() {
+        if (isDelegating()) {
+            return socket.getLocalPort();
+        }
+        return super.getLocalPort();
+    }
+
+    @Override
+    public SocketAddress getRemoteSocketAddress() {
+        if (isDelegating()) {
+            return socket.getRemoteSocketAddress();
+        }
+        return super.getRemoteSocketAddress();
+    }
+
+    @Override
+    public SocketAddress getLocalSocketAddress() {
+        if (isDelegating()) {
+            return socket.getLocalSocketAddress();
+        }
+        return super.getLocalSocketAddress();
+    }
+
+    @Override
+    public final int getPort() {
+        if (isDelegating()) {
+            return socket.getPort();
+        }
+
+        if (peerPort != -1) {
+            // Return the port that has been explicitly set in the constructor.
+            return peerPort;
+        }
+        return super.getPort();
+    }
+
+    @Override
+    public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
+        checkArgument(listener != null, "Provided listener is null");
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
+        checkArgument(listener != null, "Provided listener is null");
+        if (!listeners.remove(listener)) {
+            throw new IllegalArgumentException("Provided listener is not registered");
+        }
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java 6.
+    public abstract SSLSession getHandshakeSession();
+
+    /* @Override */
+    public FileDescriptor getFileDescriptor$() {
+        if (isDelegating()) {
+            return Platform.getFileDescriptor(socket);
+        }
+        return Platform.getFileDescriptorFromSSLSocket(this);
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public final void setSoTimeout(int readTimeoutMilliseconds) throws SocketException {
+        if (isDelegating()) {
+            socket.setSoTimeout(readTimeoutMilliseconds);
+        } else {
+            super.setSoTimeout(readTimeoutMilliseconds);
+            this.readTimeoutMilliseconds = readTimeoutMilliseconds;
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public final int getSoTimeout() throws SocketException {
+        if (isDelegating()) {
+            return socket.getSoTimeout();
+        }
+        return readTimeoutMilliseconds;
+    }
+
+    @Override
+    public final void sendUrgentData(int data) throws IOException {
+        throw new SocketException("Method sendUrgentData() is not supported.");
+    }
+
+    @Override
+    public final void setOOBInline(boolean on) throws SocketException {
+        throw new SocketException("Method setOOBInline() is not supported.");
+    }
+
+    @Override
+    public boolean getOOBInline() throws SocketException {
+        return false;
+    }
+
+    @Override
+    public SocketChannel getChannel() {
+        // TODO(nmittler): Support channels?
+        return null;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        if (isDelegating()) {
+            return socket.getInputStream();
+        }
+        return super.getInputStream();
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        if (isDelegating()) {
+            return socket.getOutputStream();
+        }
+        return super.getOutputStream();
+    }
+
+    @Override
+    public void setTcpNoDelay(boolean on) throws SocketException {
+        if (isDelegating()) {
+            socket.setTcpNoDelay(on);
+        } else {
+            super.setTcpNoDelay(on);
+        }
+    }
+
+    @Override
+    public boolean getTcpNoDelay() throws SocketException {
+        if (isDelegating()) {
+            return socket.getTcpNoDelay();
+        }
+        return super.getTcpNoDelay();
+    }
+
+    @Override
+    public void setSoLinger(boolean on, int linger) throws SocketException {
+        if (isDelegating()) {
+            socket.setSoLinger(on, linger);
+        } else {
+            super.setSoLinger(on, linger);
+        }
+    }
+
+    @Override
+    public int getSoLinger() throws SocketException {
+        if (isDelegating()) {
+            return socket.getSoLinger();
+        }
+        return super.getSoLinger();
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void setSendBufferSize(int size) throws SocketException {
+        if (isDelegating()) {
+            socket.setSendBufferSize(size);
+        } else {
+            super.setSendBufferSize(size);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public int getSendBufferSize() throws SocketException {
+        if (isDelegating()) {
+            return socket.getSendBufferSize();
+        }
+        return super.getSendBufferSize();
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void setReceiveBufferSize(int size) throws SocketException {
+        if (isDelegating()) {
+            socket.setReceiveBufferSize(size);
+        } else {
+            super.setReceiveBufferSize(size);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public int getReceiveBufferSize() throws SocketException {
+        if (isDelegating()) {
+            return socket.getReceiveBufferSize();
+        }
+        return super.getReceiveBufferSize();
+    }
+
+    @Override
+    public void setKeepAlive(boolean on) throws SocketException {
+        if (isDelegating()) {
+            socket.setKeepAlive(on);
+        } else {
+            super.setKeepAlive(on);
+        }
+    }
+
+    @Override
+    public boolean getKeepAlive() throws SocketException {
+        if (isDelegating()) {
+            return socket.getKeepAlive();
+        }
+        return super.getKeepAlive();
+    }
+
+    @Override
+    public void setTrafficClass(int tc) throws SocketException {
+        if (isDelegating()) {
+            socket.setTrafficClass(tc);
+        } else {
+            super.setTrafficClass(tc);
+        }
+    }
+
+    @Override
+    public int getTrafficClass() throws SocketException {
+        if (isDelegating()) {
+            return socket.getTrafficClass();
+        }
+        return super.getTrafficClass();
+    }
+
+    @Override
+    public void setReuseAddress(boolean on) throws SocketException {
+        if (isDelegating()) {
+            socket.setReuseAddress(on);
+        } else {
+            super.setReuseAddress(on);
+        }
+    }
+
+    @Override
+    public boolean getReuseAddress() throws SocketException {
+        if (isDelegating()) {
+            return socket.getReuseAddress();
+        }
+        return super.getReuseAddress();
+    }
+
+    @Override
+    public void shutdownInput() throws IOException {
+        if (isDelegating()) {
+            socket.shutdownInput();
+        } else {
+            super.shutdownInput();
+        }
+    }
+
+    @Override
+    public void shutdownOutput() throws IOException {
+        if (isDelegating()) {
+            socket.shutdownOutput();
+        } else {
+            super.shutdownOutput();
+        }
+    }
+
+    @Override
+    public boolean isConnected() {
+        if (isDelegating()) {
+            return socket.isConnected();
+        }
+        return super.isConnected();
+    }
+
+    @Override
+    public boolean isBound() {
+        if (isDelegating()) {
+            return socket.isBound();
+        }
+        return super.isBound();
+    }
+
+    @Override
+    public boolean isClosed() {
+        if (isDelegating()) {
+            return socket.isClosed();
+        }
+        return super.isClosed();
+    }
+
+    @Override
+    public boolean isInputShutdown() {
+        if (isDelegating()) {
+            return socket.isInputShutdown();
+        }
+        return super.isInputShutdown();
+    }
+
+    @Override
+    public boolean isOutputShutdown() {
+        if (isDelegating()) {
+            return socket.isOutputShutdown();
+        }
+        return super.isOutputShutdown();
+    }
+
+    @Override
+    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+        if (isDelegating()) {
+            socket.setPerformancePreferences(connectionTime, latency, bandwidth);
+        } else {
+            super.setPerformancePreferences(connectionTime, latency, bandwidth);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("SSL socket over ");
+        if (isDelegating()) {
+            builder.append(socket.toString());
+        } else {
+            builder.append(super.toString());
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Returns the hostname that was supplied during socket creation. No DNS resolution is
+     * attempted before returning the hostname.
+     */
+    String getHostname() {
+        return peerHostname;
+    }
+
+    /**
+     * This method enables Server Name Indication
+     *
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    void setHostname(String hostname) {
+        peerHostname = hostname;
+    }
+
+    /**
+     * For the purposes of an SSLSession, we want a way to represent the supplied hostname
+     * or the IP address in a textual representation. We do not want to perform reverse DNS
+     * lookups on this address.
+     */
+    String getHostnameOrIP() {
+        if (peerHostname != null) {
+            return peerHostname;
+        }
+
+        InetAddress peerAddress = getInetAddress();
+        if (peerAddress != null) {
+            return peerAddress.getHostAddress();
+        }
+
+        return null;
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+        throw new SocketException("Method setSoWriteTimeout() is not supported.");
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    int getSoWriteTimeout() throws SocketException {
+        return 0;
+    }
+
+    /**
+     * Set the handshake timeout on this socket.  This timeout is specified in
+     * milliseconds and will be used only during the handshake process.
+     */
+    void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+        throw new SocketException("Method setHandshakeTimeout() is not supported.");
+    }
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param useSessionTickets True to enable session tickets
+     */
+    abstract void setUseSessionTickets(boolean useSessionTickets);
+
+    /**
+     * Enables/disables TLS Channel ID for this server socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has already
+     *         started.
+     */
+    abstract void setChannelIdEnabled(boolean enabled);
+
+    /**
+     * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
+     * handshake completes.
+     *
+     * @return channel ID or {@code null} if not available.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has not yet
+     *         completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    abstract byte[] getChannelId() throws SSLException;
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
+     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
+     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
+     *
+     * @throws IllegalStateException if this is a server socket or if the handshake has already
+     *         started.
+     */
+    abstract void setChannelIdPrivateKey(PrivateKey privateKey);
+
+    /**
+     * Returns null always for backward compatibility.
+     */
+    byte[] getNpnSelectedProtocol() {
+        return null;
+    }
+
+    /**
+     * This method does nothing and is kept for backward compatibility.
+     */
+    void setNpnProtocols(byte[] npnProtocols) {}
+
+    /**
+     * Returns the protocol agreed upon by client and server, or {@code null} if
+     * no protocol was agreed upon.
+     */
+    abstract byte[] getAlpnSelectedProtocol();
+
+    /**
+     * Sets the list of ALPN protocols. This method internally converts the protocols to their
+     * wire-format form.
+     *
+     * @param alpnProtocols the list of ALPN protocols
+     * @see #setAlpnProtocols(byte[])
+     */
+    abstract void setAlpnProtocols(String[] alpnProtocols);
+
+    /**
+     * Alternate version of {@link #setAlpnProtocols(String[])} that directly sets the list of
+     * ALPN in the wire-format form used by BoringSSL (length-prefixed 8-bit strings).
+     * Requires that all strings be encoded with US-ASCII.
+     *
+     * @param alpnProtocols the encoded form of the ALPN protocol list
+     * @see #setAlpnProtocols(String[])
+     */
+    abstract void setAlpnProtocols(byte[] alpnProtocols);
+
+    /**
+     * Called by {@link #notifyHandshakeCompletedListeners()} to get the currently active session.
+     * Unlike {@link #getSession()}, this method must not block.
+     */
+    abstract SSLSession getActiveSession();
+
+    final PeerInfoProvider peerInfoProvider() {
+        return peerInfoProvider;
+    }
+
+    final void checkOpen() throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+    }
+
+    final void notifyHandshakeCompletedListeners() {
+        if (listeners != null && !listeners.isEmpty()) {
+            // notify the listeners
+            HandshakeCompletedEvent event = new HandshakeCompletedEvent(this, getActiveSession());
+            for (HandshakeCompletedListener listener : listeners) {
+                try {
+                    listener.handshakeCompleted(event);
+                } catch (RuntimeException e) {
+                    // The RI runs the handlers in a separate thread,
+                    // which we do not. But we try to preserve their
+                    // behavior of logging a problem and not killing
+                    // the handshaking thread just because a listener
+                    // has a problem.
+                    Thread thread = Thread.currentThread();
+                    thread.getUncaughtExceptionHandler().uncaughtException(thread, e);
+                }
+            }
+        }
+    }
+
+    private boolean isDelegating() {
+        // Checking for null to handle the case of calling virtual methods in the super class
+        // constructor.
+        return socket != null && socket != this;
+    }
+}
diff --git a/common/src/main/java/org/conscrypt/Conscrypt.java b/common/src/main/java/org/conscrypt/Conscrypt.java
index 14fe6bd..10d23d1 100644
--- a/common/src/main/java/org/conscrypt/Conscrypt.java
+++ b/common/src/main/java/org/conscrypt/Conscrypt.java
@@ -15,9 +15,7 @@
  */
 package org.conscrypt;
 
-import java.io.FileDescriptor;
 import java.io.UnsupportedEncodingException;
-import java.net.SocketException;
 import java.nio.ByteBuffer;
 import java.security.KeyManagementException;
 import java.security.PrivateKey;
@@ -168,25 +166,15 @@
          * Indicates whether the given socket is a Conscrypt socket.
          */
         public static boolean isConscrypt(SSLSocket socket) {
-            return socket instanceof OpenSSLSocketImpl;
+            return socket instanceof AbstractConscryptSocket;
         }
 
-        private static OpenSSLSocketImpl toConscrypt(SSLSocket socket) {
+        private static AbstractConscryptSocket toConscrypt(SSLSocket socket) {
             if (!isConscrypt(socket)) {
                 throw new IllegalArgumentException(
                         "Not a conscrypt socket: " + socket.getClass().getName());
             }
-            return (OpenSSLSocketImpl) socket;
-        }
-
-        /**
-         * This method enables session ticket support.
-         *
-         * @param socket the socket
-         * @param useSessionTickets True to enable session tickets
-         */
-        public static void setUseSessionTickets(SSLSocket socket, boolean useSessionTickets) {
-            toConscrypt(socket).setUseSessionTickets(useSessionTickets);
+            return (AbstractConscryptSocket) socket;
         }
 
         /**
@@ -218,34 +206,13 @@
         }
 
         /**
-         * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+         * This method enables session ticket support.
+         *
+         * @param socket the socket
+         * @param useSessionTickets True to enable session tickets
          */
-        public static void setSoWriteTimeout(SSLSocket socket, int writeTimeoutMilliseconds)
-                throws SocketException {
-            toConscrypt(socket).setSoWriteTimeout(writeTimeoutMilliseconds);
-        }
-
-        /**
-         * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
-         */
-        public static int getSoWriteTimeout(SSLSocket socket) throws SocketException {
-            return toConscrypt(socket).getSoWriteTimeout();
-        }
-
-        /**
-         * Set the handshake timeout on this socket.  This timeout is specified in
-         * milliseconds and will be used only during the handshake process.
-         */
-        public static void setHandshakeTimeout(SSLSocket socket, int handshakeTimeoutMilliseconds)
-                throws SocketException {
-            toConscrypt(socket).setHandshakeTimeout(handshakeTimeoutMilliseconds);
-        }
-
-        /**
-         * Gets the underlying file descriptor for the given socket.
-         */
-        public static FileDescriptor getFileDescriptor(SSLSocket socket) {
-            return toConscrypt(socket).getFileDescriptor$();
+        public static void setUseSessionTickets(SSLSocket socket, boolean useSessionTickets) {
+            toConscrypt(socket).setUseSessionTickets(useSessionTickets);
         }
 
         /**
diff --git a/common/src/main/java/org/conscrypt/ConscryptEngine.java b/common/src/main/java/org/conscrypt/ConscryptEngine.java
index d62323b..d7b6d12 100644
--- a/common/src/main/java/org/conscrypt/ConscryptEngine.java
+++ b/common/src/main/java/org/conscrypt/ConscryptEngine.java
@@ -301,8 +301,8 @@
     }
 
     /**
-     * This method enables Server Name Indication (SNI) and overrides the hostname supplied
-     * during engine creation.
+     * This method enables Server Name Indication (SNI) and overrides the {@link PeerInfoProvider}
+     * supplied during engine creation.
      */
     void setHostname(String hostname) {
         sslParameters.setUseSni(hostname != null);
@@ -310,12 +310,12 @@
     }
 
     /**
-     * Returns either the hostname supplied during engine creation or via
-     * {@link #setHostname(String)}. No DNS resolution is attempted before
+     * Returns the hostname from {@link #setHostname(String)} or supplied by the
+     * {@link PeerInfoProvider} upon creation. No DNS resolution is attempted before
      * returning the hostname.
      */
     String getHostname() {
-        return peerHostname;
+        return peerHostname != null ? peerHostname : peerInfoProvider.getHostname();
     }
 
     @Override
diff --git a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
new file mode 100644
index 0000000..433a6bc
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
@@ -0,0 +1,763 @@
+/*
+ * Copyright 2016 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 org.conscrypt;
+
+import static javax.net.ssl.SSLEngineResult.Status.OK;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_COMPLETED;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_STARTED;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_NEW;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_READY;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_READY_HANDSHAKE_CUT_THROUGH;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.security.PrivateKey;
+import javax.crypto.SecretKey;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509KeyManager;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * Implements crypto handling by delegating to {@link ConscryptEngine}.
+ */
+final class ConscryptEngineSocket extends OpenSSLSocketImpl
+        implements SSLParametersImpl.AliasChooser, SSLParametersImpl.PSKCallbacks {
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
+
+    private final ConscryptEngine engine;
+    private final Object stateLock = new Object();
+    private final Object handshakeLock = new Object();
+
+    private SSLOutputStream out;
+    private SSLInputStream in;
+
+    // @GuardedBy("stateLock");
+    private int state = STATE_NEW;
+
+    ConscryptEngineSocket(SSLParametersImpl sslParameters) throws IOException {
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(String hostname, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(hostname, port);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(InetAddress address, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(address, port);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(String hostname, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(address, port, clientAddress, clientPort);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(Socket socket, String hostname, int port, boolean autoClose,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(socket, hostname, port, autoClose);
+        engine = newEngine(sslParameters, this);
+    }
+
+    private static ConscryptEngine newEngine(
+            SSLParametersImpl sslParameters, final ConscryptEngineSocket socket) {
+        ConscryptEngine engine = new ConscryptEngine(sslParameters, socket.peerInfoProvider());
+
+        // When the handshake completes, notify any listeners.
+        engine.setHandshakeListener(new HandshakeListener() {
+            /**
+             * Protected by {@code stateLock}
+             */
+            @Override
+            public void onHandshakeFinished() {
+                // Just call the outer class method.
+                socket.onHandshakeFinished();
+            }
+        });
+
+        // Transition the engine state to MODE_SET
+        engine.setUseClientMode(sslParameters.getUseClientMode());
+        return engine;
+    }
+
+    @Override
+    public SSLParameters getSSLParameters() {
+        return engine.getSSLParameters();
+    }
+
+    @Override
+    public void setSSLParameters(SSLParameters sslParameters) {
+        engine.setSSLParameters(sslParameters);
+    }
+
+    @Override
+    public void startHandshake() throws IOException {
+        checkOpen();
+
+        if (isHandshakeFinished()) {
+            // TODO(nmittler): Handle renegotiation.
+            return;
+        }
+
+        try {
+            synchronized (handshakeLock) {
+                // Only lock stateLock when we begin the handshake. This is done so that we don't
+                // hold the stateLock when we invoke the handshake completion listeners.
+                synchronized (stateLock) {
+                    // Initialize the handshake if we haven't already.
+                    if (state == STATE_NEW) {
+                        state = STATE_HANDSHAKE_STARTED;
+                        engine.beginHandshake();
+                        in = new SSLInputStream();
+                        out = new SSLOutputStream();
+                    } else {
+                        // We've either started the handshake already or have been closed.
+                        // Do nothing in both cases.
+                        return;
+                    }
+                }
+
+                boolean finished = false;
+                while (!finished) {
+                    switch (engine.getHandshakeStatus()) {
+                        case NEED_UNWRAP:
+                            if (in.readInternal(EmptyArray.BYTE, 0, 0) < 0) {
+                                // Can't complete the handshake due to EOF.
+                                throw SSLUtils.toSSLHandshakeException(new EOFException());
+                            }
+                            break;
+                        case NEED_WRAP: {
+                            out.writeInternal(EMPTY_BUFFER);
+                            // Always flush handshake frames immediately.
+                            out.flushInternal();
+                            break;
+                        }
+                        case NEED_TASK:
+                            // Should never get here, since our engine never provides tasks.
+                            throw new IllegalStateException("Engine tasks are unsupported");
+                        case NOT_HANDSHAKING:
+                        case FINISHED:
+                            // Handshake is complete.
+                            finished = true;
+                            break;
+                        default: {
+                            throw new IllegalStateException(
+                                    "Unknown handshake status: " + engine.getHandshakeStatus());
+                        }
+                    }
+                }
+            }
+        } catch (SSLException e) {
+            close();
+            throw e;
+        } catch (IOException e) {
+            close();
+            throw e;
+        } catch (Exception e) {
+            close();
+            // Convert anything else to a handshake exception.
+            throw SSLUtils.toSSLHandshakeException(e);
+        }
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        checkOpen();
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the input stream but
+        // all reads on it will throw.
+        waitForHandshake();
+        return in;
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        checkOpen();
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the input stream but
+        // all reads on it will throw.
+        waitForHandshake();
+
+        return out;
+    }
+
+    @Override
+    public SSLSession getHandshakeSession() {
+        return engine.handshakeSession();
+    }
+
+    @Override
+    public SSLSession getSession() {
+        SSLSession session = engine.getSession();
+        if (session == null) {
+            boolean handshakeCompleted = false;
+            try {
+                if (isConnected()) {
+                    waitForHandshake();
+                    handshakeCompleted = true;
+                }
+            } catch (IOException e) {
+                // Fall through.
+            }
+
+            if (!handshakeCompleted) {
+                // return an invalid session with
+                // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
+                return SSLNullSession.getNullSession();
+            }
+            session = engine.getSession();
+        }
+        return session;
+    }
+
+    @Override
+    SSLSession getActiveSession() {
+        return engine.getSession();
+    }
+
+    @Override
+    public boolean getEnableSessionCreation() {
+        return engine.getEnableSessionCreation();
+    }
+
+    @Override
+    public void setEnableSessionCreation(boolean flag) {
+        engine.setEnableSessionCreation(flag);
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return engine.getSupportedCipherSuites();
+    }
+
+    @Override
+    public String[] getEnabledCipherSuites() {
+        return engine.getEnabledCipherSuites();
+    }
+
+    @Override
+    public void setEnabledCipherSuites(String[] suites) {
+        engine.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public String[] getSupportedProtocols() {
+        return engine.getSupportedProtocols();
+    }
+
+    @Override
+    public String[] getEnabledProtocols() {
+        return engine.getEnabledProtocols();
+    }
+
+    @Override
+    public void setEnabledProtocols(String[] protocols) {
+        engine.setEnabledProtocols(protocols);
+    }
+
+    /**
+     * This method enables Server Name Indication
+     *
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    @Override
+    public void setHostname(String hostname) {
+        engine.setHostname(hostname);
+        super.setHostname(hostname);
+    }
+
+    @Override
+    public void setUseSessionTickets(boolean useSessionTickets) {
+        engine.setUseSessionTickets(useSessionTickets);
+    }
+
+    @Override
+    public void setChannelIdEnabled(boolean enabled) {
+        engine.setChannelIdEnabled(enabled);
+    }
+
+    @Override
+    public byte[] getChannelId() throws SSLException {
+        return engine.getChannelId();
+    }
+
+    @Override
+    public void setChannelIdPrivateKey(PrivateKey privateKey) {
+        engine.setChannelIdPrivateKey(privateKey);
+    }
+
+    @Override
+    public boolean getUseClientMode() {
+        return engine.getUseClientMode();
+    }
+
+    @Override
+    public void setUseClientMode(boolean mode) {
+        engine.setUseClientMode(mode);
+    }
+
+    @Override
+    public boolean getWantClientAuth() {
+        return engine.getWantClientAuth();
+    }
+
+    @Override
+    public boolean getNeedClientAuth() {
+        return engine.getNeedClientAuth();
+    }
+
+    @Override
+    public void setNeedClientAuth(boolean need) {
+        engine.setNeedClientAuth(need);
+    }
+
+    @Override
+    public void setWantClientAuth(boolean want) {
+        engine.setWantClientAuth(want);
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void close() throws IOException {
+        // TODO: Close SSL sockets using a background thread so they close gracefully.
+
+        synchronized (stateLock) {
+            if (state == STATE_CLOSED) {
+                // close() has already been called, so do nothing and return.
+                return;
+            }
+
+            state = STATE_CLOSED;
+
+            stateLock.notifyAll();
+        }
+
+        // Close the underlying socket.
+        super.close();
+
+        // Close the engine.
+        engine.closeInbound();
+        engine.closeOutbound();
+    }
+
+    @Override
+    public byte[] getAlpnSelectedProtocol() {
+        return engine.getAlpnSelectedProtocol();
+    }
+
+    @Override
+    public void setAlpnProtocols(byte[] alpnProtocols) {
+        engine.setAlpnProtocols(alpnProtocols);
+    }
+
+    @Override
+    public void setAlpnProtocols(String[] alpnProtocols) {
+        engine.setAlpnProtocols(alpnProtocols);
+    }
+
+    @Override
+    public String chooseServerAlias(X509KeyManager keyManager, String keyType) {
+        return engine.chooseServerAlias(keyManager, keyType);
+    }
+
+    @Override
+    public String chooseClientAlias(
+            X509KeyManager keyManager, X500Principal[] issuers, String[] keyTypes) {
+        return engine.chooseClientAlias(keyManager, issuers, keyTypes);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public String chooseServerPSKIdentityHint(PSKKeyManager keyManager) {
+        return engine.chooseServerPSKIdentityHint(keyManager);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) {
+        return engine.chooseClientPSKIdentity(keyManager, identityHint);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) {
+        return engine.getPSKKey(keyManager, identityHint, identity);
+    }
+
+    private boolean isHandshakeFinished() {
+        return state >= STATE_READY_HANDSHAKE_CUT_THROUGH;
+    }
+
+    private void onHandshakeFinished() {
+        boolean notify = false;
+        synchronized (stateLock) {
+            if (state != STATE_CLOSED) {
+                if (state == STATE_HANDSHAKE_STARTED) {
+                    state = STATE_READY_HANDSHAKE_CUT_THROUGH;
+                } else if (state == STATE_HANDSHAKE_COMPLETED) {
+                    state = STATE_READY;
+                }
+
+                // Unblock threads that are waiting for our state to transition
+                // into STATE_READY or STATE_READY_HANDSHAKE_CUT_THROUGH.
+                stateLock.notifyAll();
+                notify = true;
+            }
+        }
+
+        if (notify) {
+            notifyHandshakeCompletedListeners();
+        }
+    }
+
+    /**
+     * Waits for the handshake to complete.
+     */
+    private void waitForHandshake() throws IOException {
+        startHandshake();
+
+        synchronized (stateLock) {
+            while (state != STATE_READY && state != STATE_READY_HANDSHAKE_CUT_THROUGH
+                    && state != STATE_CLOSED) {
+                try {
+                    stateLock.wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new IOException("Interrupted waiting for handshake", e);
+                }
+            }
+
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed");
+            }
+        }
+    }
+
+    private OutputStream getUnderlyingOutputStream() throws IOException {
+        return super.getOutputStream();
+    }
+
+    private InputStream getUnderlyingInputStream() throws IOException {
+        return super.getInputStream();
+    }
+
+    private SocketChannel getUnderlyingChannel() throws IOException {
+        return super.getChannel();
+    }
+
+    /**
+     * Wrap bytes written to the underlying socket.
+     */
+    private final class SSLOutputStream extends OutputStream {
+        private final Object writeLock = new Object();
+        private ByteBuffer target;
+        private OutputStream socketOutputStream;
+        private SocketChannel socketChannel;
+
+        SSLOutputStream() {}
+
+        @Override
+        public void close() throws IOException {
+            ConscryptEngineSocket.this.close();
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                write(new byte[] {(byte) b});
+            }
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                writeInternal(ByteBuffer.wrap(b));
+            }
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                writeInternal(ByteBuffer.wrap(b, off, len));
+            }
+        }
+
+        private void writeInternal(ByteBuffer buffer) throws IOException {
+            Platform.blockGuardOnNetwork();
+            checkOpen();
+            init();
+
+            // Need to loop through at least once to enable handshaking where no application
+            // bytes are
+            // processed.
+            int len = buffer.remaining();
+            SSLEngineResult engineResult;
+            do {
+                target.clear();
+                engineResult = engine.wrap(buffer, target);
+                if (engineResult.getStatus() != OK) {
+                    throw new SSLException("Unexpected engine result " + engineResult.getStatus());
+                }
+                if (target.position() != engineResult.bytesProduced()) {
+                    throw new SSLException("Engine bytesProduced " + engineResult.bytesProduced()
+                            + " does not match bytes written " + target.position());
+                }
+                len -= engineResult.bytesConsumed();
+                if (len != buffer.remaining()) {
+                    throw new SSLException("Engine did not read the correct number of bytes");
+                }
+
+                target.flip();
+
+                // Write the data to the socket.
+                writeToSocket();
+            } while (len > 0);
+        }
+
+        @Override
+        public void flush() throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                flushInternal();
+            }
+        }
+
+        private void flushInternal() throws IOException {
+            checkOpen();
+            init();
+            socketOutputStream.flush();
+        }
+
+        private void init() throws IOException {
+            if (socketOutputStream == null) {
+                socketOutputStream = getUnderlyingOutputStream();
+                socketChannel = getUnderlyingChannel();
+                if (socketChannel != null) {
+                    // Optimization. Using direct buffers wherever possible to avoid passing
+                    // arrays to JNI.
+                    target = ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize());
+                } else {
+                    target = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
+                }
+            }
+        }
+
+        private void writeToSocket() throws IOException {
+            // Write the data to the socket.
+            if (socketChannel != null) {
+                // Loop until all of the data is written to the channel. Typically,
+                // SocketChannel writes will return only after all bytes are written,
+                // so we won't really loop here.
+                while (target.hasRemaining()) {
+                    socketChannel.write(target);
+                }
+            } else {
+                // Target is a heap buffer.
+                socketOutputStream.write(target.array(), 0, target.limit());
+            }
+        }
+    }
+
+    /**
+     * Unwrap bytes read from the underlying socket.
+     */
+    private final class SSLInputStream extends InputStream {
+        private final Object readLock = new Object();
+        private final byte[] singleByte = new byte[1];
+        private final ByteBuffer fromEngine;
+        private ByteBuffer fromSocket;
+        private InputStream socketInputStream;
+        private SocketChannel socketChannel;
+
+        SSLInputStream() {
+            fromEngine = ByteBuffer.allocateDirect(engine.getSession().getApplicationBufferSize());
+            // Initially fromEngine.remaining() == 0.
+            fromEngine.flip();
+        }
+
+        @Override
+        public void close() throws IOException {
+            ConscryptEngineSocket.this.close();
+        }
+
+        @Override
+        public int read() throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                // Handle returning of -1 if EOF is reached.
+                int count = read(singleByte, 0, 1);
+                if (count == -1) {
+                    // Handle EOF.
+                    return -1;
+                }
+                if (count != 1) {
+                    throw new SSLException("read incorrect number of bytes " + count);
+                }
+                return (int) singleByte[0];
+            }
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                return read(b, 0, b.length);
+            }
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                return readInternal(b, off, len);
+            }
+        }
+
+        @Override
+        public int available() throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                init();
+                return fromEngine.remaining()
+                        + (fromSocket.hasRemaining() || socketInputStream.available() > 0 ? 1 : 0);
+            }
+        }
+
+        private int readInternal(byte[] b, int off, int len) throws IOException {
+            Platform.blockGuardOnNetwork();
+            checkOpen();
+
+            // Make sure the input stream has been created.
+            init();
+
+            for (;;) {
+                // Serve any remaining data from the engine first.
+                if (fromEngine.remaining() > 0) {
+                    int readFromEngine = Math.min(fromEngine.remaining(), len);
+                    fromEngine.get(b, off, readFromEngine);
+                    return readFromEngine;
+                }
+
+                // Try to unwrap any data already in the socket buffer.
+                boolean needMoreDataFromSocket = true;
+
+                // Unwrap the unencrypted bytes into the engine buffer.
+                fromSocket.flip();
+                fromEngine.clear();
+                SSLEngineResult engineResult = engine.unwrap(fromSocket, fromEngine);
+                // Shift any remaining data to the beginning of the buffer so that
+                // we can accommodate the next full packet. After this is called,
+                // limit will be restored to capacity and position will point just
+                // past the end of the data.
+                fromSocket.compact();
+                fromEngine.flip();
+
+                switch (engineResult.getStatus()) {
+                    case BUFFER_UNDERFLOW: {
+                        if (engineResult.bytesProduced() == 0) {
+                            // Need to read more data from the socket.
+                            break;
+                        }
+                        // Also serve the data that was produced.
+                        needMoreDataFromSocket = false;
+                        break;
+                    }
+                    case OK: {
+                        // We processed the entire packet successfully.
+                        needMoreDataFromSocket = false;
+                        break;
+                    }
+                    case CLOSED: {
+                        // EOF
+                        return -1;
+                    }
+                    default: {
+                        // Anything else is an error.
+                        throw new SSLException(
+                                "Unexpected engine result " + engineResult.getStatus());
+                    }
+                }
+
+                if (!needMoreDataFromSocket && engineResult.bytesProduced() == 0) {
+                    // Read successfully, but produced no data. Possibly part of a
+                    // handshake.
+                    return 0;
+                }
+
+                // Read more data from the socket.
+                if (needMoreDataFromSocket && readFromSocket() == -1) {
+                    // Failed to read the next encrypted packet before reaching EOF.
+                    return -1;
+                }
+
+                // Continue the loop and return the data from the engine buffer.
+            }
+        }
+
+        private void init() throws IOException {
+            if (socketInputStream == null) {
+                socketInputStream = getUnderlyingInputStream();
+                socketChannel = getUnderlyingChannel();
+                if (socketChannel != null) {
+                    fromSocket =
+                            ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize());
+                } else {
+                    fromSocket = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
+                }
+            }
+        }
+
+        private int readFromSocket() throws IOException {
+            if (socketChannel != null) {
+                return socketChannel.read(fromSocket);
+            }
+            // Read directly to the underlying array and increment the buffer position if
+            // appropriate.
+            int read = socketInputStream.read(
+                    fromSocket.array(), fromSocket.position(), fromSocket.remaining());
+            if (read > 0) {
+                fromSocket.position(fromSocket.position() + read);
+            }
+            return read;
+        }
+    }
+}
diff --git a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
new file mode 100644
index 0000000..1fb9ee8
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
@@ -0,0 +1,1092 @@
+/*
+ * Copyright (C) 2017 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 org.conscrypt;
+
+import static org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_COMPLETED;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_STARTED;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_NEW;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_READY;
+import static org.conscrypt.SSLUtils.EngineStates.STATE_READY_HANDSHAKE_CUT_THROUGH;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.interfaces.ECKey;
+import java.security.spec.ECParameterSpec;
+import javax.crypto.SecretKey;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLProtocolException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * Implementation of the class OpenSSLSocketImpl based on OpenSSL.
+ * <p>
+ * Extensions to SSLSocket include:
+ * <ul>
+ * <li>handshake timeout
+ * <li>session tickets
+ * <li>Server Name Indication
+ * </ul>
+ */
+final class ConscryptFileDescriptorSocket extends OpenSSLSocketImpl
+        implements NativeCrypto.SSLHandshakeCallbacks, SSLParametersImpl.AliasChooser,
+                   SSLParametersImpl.PSKCallbacks {
+    private static final boolean DBG_STATE = false;
+
+    /**
+     * Protects handshakeStarted and handshakeCompleted.
+     */
+    private final Object stateLock = new Object();
+
+    // @GuardedBy("stateLock");
+    private int state = STATE_NEW;
+
+    /**
+     * Protected by synchronizing on stateLock. Starts as 0, set by
+     * startHandshake, reset to 0 on close.
+     */
+    // @GuardedBy("stateLock");
+    private long sslNativePointer;
+
+    /**
+     * Protected by synchronizing on stateLock. Starts as null, set by
+     * getInputStream.
+     */
+    // @GuardedBy("stateLock");
+    private SSLInputStream is;
+
+    /**
+     * Protected by synchronizing on stateLock. Starts as null, set by
+     * getInputStream.
+     */
+    // @GuardedBy("stateLock");
+    private SSLOutputStream os;
+
+    private final SSLParametersImpl sslParameters;
+
+    /*
+     * A CloseGuard object on Android. On other platforms, this is nothing.
+     */
+    private final Object guard = Platform.closeGuardGet();
+
+    /**
+     * Private key for the TLS Channel ID extension. This field is client-side
+     * only. Set during startHandshake.
+     */
+    private OpenSSLKey channelIdPrivateKey;
+
+    /** Set during startHandshake. */
+    private AbstractOpenSSLSession sslSession;
+
+    /** Used during handshake callbacks. */
+    private AbstractOpenSSLSession handshakeSession;
+
+    private int writeTimeoutMilliseconds = 0;
+    private int handshakeTimeoutMilliseconds = -1; // -1 = same as timeout; 0 = infinite
+
+    ConscryptFileDescriptorSocket(SSLParametersImpl sslParameters) throws IOException {
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptFileDescriptorSocket(String hostname, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(hostname, port);
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptFileDescriptorSocket(InetAddress address, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(address, port);
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptFileDescriptorSocket(String hostname, int port, InetAddress clientAddress,
+            int clientPort, SSLParametersImpl sslParameters) throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptFileDescriptorSocket(InetAddress address, int port, InetAddress clientAddress,
+            int clientPort, SSLParametersImpl sslParameters) throws IOException {
+        super(address, port, clientAddress, clientPort);
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptFileDescriptorSocket(Socket socket, String hostname, int port, boolean autoClose,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(socket, hostname, port, autoClose);
+        this.sslParameters = sslParameters;
+    }
+
+    /**
+     * Starts a TLS/SSL handshake on this connection using some native methods
+     * from the OpenSSL library. It can negotiate new encryption keys, change
+     * cipher suites, or initiate a new session. The certificate chain is
+     * verified if the correspondent property in java.Security is set. All
+     * listeners are notified at the end of the TLS/SSL handshake.
+     */
+    @Override
+    public void startHandshake() throws IOException {
+        checkOpen();
+        synchronized (stateLock) {
+            if (state == STATE_NEW) {
+                state = STATE_HANDSHAKE_STARTED;
+            } else {
+                // We've either started the handshake already or have been closed.
+                // Do nothing in both cases.
+                return;
+            }
+        }
+
+        final boolean client = sslParameters.getUseClientMode();
+
+        sslNativePointer = 0;
+        boolean releaseResources = true;
+        try {
+            final AbstractSessionContext sessionContext = sslParameters.getSessionContext();
+            sslNativePointer = NativeCrypto.SSL_new(sessionContext.sslCtxNativePointer);
+            Platform.closeGuardOpen(guard, "close");
+
+            boolean enableSessionCreation = getEnableSessionCreation();
+            if (!enableSessionCreation) {
+                NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer,
+                        enableSessionCreation);
+            }
+
+            // Allow servers to trigger renegotiation. Some inadvisable server
+            // configurations cause them to attempt to renegotiate during
+            // certain protocols.
+            NativeCrypto.SSL_accept_renegotiations(sslNativePointer);
+
+            if (client) {
+                NativeCrypto.SSL_set_connect_state(sslNativePointer);
+
+                // Configure OCSP and CT extensions for client
+                NativeCrypto.SSL_enable_ocsp_stapling(sslNativePointer);
+                if (sslParameters.isCTVerificationEnabled(getHostname())) {
+                    NativeCrypto.SSL_enable_signed_cert_timestamps(sslNativePointer);
+                }
+            } else {
+                NativeCrypto.SSL_set_accept_state(sslNativePointer);
+
+                // Configure OCSP for server
+                if (sslParameters.getOCSPResponse() != null) {
+                    NativeCrypto.SSL_enable_ocsp_stapling(sslNativePointer);
+                }
+            }
+
+            final AbstractOpenSSLSession sessionToReuse =
+                    sslParameters.getSessionToReuse(sslNativePointer, getHostnameOrIP(), getPort());
+            sslParameters.setSSLParameters(sslNativePointer, this, this, getHostname());
+            sslParameters.setCertificateValidation(sslNativePointer);
+            sslParameters.setTlsChannelId(sslNativePointer, channelIdPrivateKey);
+
+            // Temporarily use a different timeout for the handshake process
+            int savedReadTimeoutMilliseconds = getSoTimeout();
+            int savedWriteTimeoutMilliseconds = getSoWriteTimeout();
+            if (handshakeTimeoutMilliseconds >= 0) {
+                setSoTimeout(handshakeTimeoutMilliseconds);
+                setSoWriteTimeout(handshakeTimeoutMilliseconds);
+            }
+
+            synchronized (stateLock) {
+                if (state == STATE_CLOSED) {
+                    return;
+                }
+            }
+
+            long sslSessionNativePointer;
+            try {
+                NativeCrypto.SSL_do_handshake(
+                        sslNativePointer, Platform.getFileDescriptor(socket), this, getSoTimeout());
+                sslSessionNativePointer = NativeCrypto.SSL_get1_session(sslNativePointer);
+            } catch (CertificateException e) {
+                SSLHandshakeException wrapper = new SSLHandshakeException(e.getMessage());
+                wrapper.initCause(e);
+                throw wrapper;
+            } catch (SSLException e) {
+                // Swallow this exception if it's thrown as the result of an interruption.
+                //
+                // TODO: SSL_read and SSL_write return -1 when interrupted, but SSL_do_handshake
+                // will throw the last sslError that it saw before sslSelect, usually SSL_WANT_READ
+                // (or WANT_WRITE). Catching that exception here doesn't seem much worse than
+                // changing the native code to return a "special" native pointer value when that
+                // happens.
+                synchronized (stateLock) {
+                    if (state == STATE_CLOSED) {
+                        return;
+                    }
+                }
+
+                // Write CCS errors to EventLog
+                String message = e.getMessage();
+                // Must match error string of SSL_R_UNEXPECTED_CCS
+                if (message.contains("unexpected CCS")) {
+                    String logMessage = String.format("ssl_unexpected_ccs: host=%s",
+                            getHostnameOrIP());
+                    Platform.logEvent(logMessage);
+                }
+
+                throw e;
+            }
+
+            boolean handshakeCompleted = false;
+            synchronized (stateLock) {
+                if (state == STATE_HANDSHAKE_COMPLETED) {
+                    handshakeCompleted = true;
+                } else if (state == STATE_CLOSED) {
+                    return;
+                }
+            }
+
+            sslSession = sslParameters.setupSession(sslSessionNativePointer, sslNativePointer,
+                    sessionToReuse, getHostnameOrIP(), getPort(), handshakeCompleted);
+
+            // Restore the original timeout now that the handshake is complete
+            if (handshakeTimeoutMilliseconds >= 0) {
+                setSoTimeout(savedReadTimeoutMilliseconds);
+                setSoWriteTimeout(savedWriteTimeoutMilliseconds);
+            }
+
+            // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
+            if (handshakeCompleted) {
+                notifyHandshakeCompletedListeners();
+            }
+
+            synchronized (stateLock) {
+                releaseResources = (state == STATE_CLOSED);
+
+                if (state == STATE_HANDSHAKE_STARTED) {
+                    state = STATE_READY_HANDSHAKE_CUT_THROUGH;
+                } else if (state == STATE_HANDSHAKE_COMPLETED) {
+                    state = STATE_READY;
+                }
+
+                if (!releaseResources) {
+                    // Unblock threads that are waiting for our state to transition
+                    // into STATE_READY or STATE_READY_HANDSHAKE_CUT_THROUGH.
+                    stateLock.notifyAll();
+                }
+            }
+        } catch (SSLProtocolException e) {
+            throw (SSLHandshakeException) new SSLHandshakeException("Handshake failed")
+                    .initCause(e);
+        } finally {
+            // on exceptional exit, treat the socket as closed
+            if (releaseResources) {
+                synchronized (stateLock) {
+                    // Mark the socket as closed since we might have reached this as
+                    // a result on an exception thrown by the handshake process.
+                    //
+                    // The state will already be set to closed if we reach this as a result of
+                    // an early return or an interruption due to a concurrent call to close().
+                    state = STATE_CLOSED;
+                    stateLock.notifyAll();
+                }
+
+                try {
+                    shutdownAndFreeSslNative();
+                } catch (IOException ignored) {
+                    // Ignored.
+                }
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / client_cert_cb
+    public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals)
+            throws CertificateEncodingException, SSLException {
+        sslParameters.chooseClientCertificate(keyTypeBytes, asn1DerEncodedPrincipals,
+                sslNativePointer, this);
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by native psk_client_callback
+    public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) {
+        return sslParameters.clientPSKKeyRequested(identityHint, identity, key, this);
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by native psk_server_callback
+    public int serverPSKKeyRequested(String identityHint, String identity, byte[] key) {
+        return sslParameters.serverPSKKeyRequested(identityHint, identity, key, this);
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / info_callback
+    public void onSSLStateChange(int type, int val) {
+        if (type != NativeConstants.SSL_CB_HANDSHAKE_DONE) {
+            return;
+        }
+
+        synchronized (stateLock) {
+            if (state == STATE_HANDSHAKE_STARTED) {
+                // If sslSession is null, the handshake was completed during
+                // the call to NativeCrypto.SSL_do_handshake and not during a
+                // later read operation. That means we do not need to fix up
+                // the SSLSession and session cache or notify
+                // HandshakeCompletedListeners, it will be done in
+                // startHandshake.
+
+                state = STATE_HANDSHAKE_COMPLETED;
+                return;
+            } else if (state == STATE_READY_HANDSHAKE_CUT_THROUGH) {
+                // We've returned from startHandshake, which means we've set a sslSession etc.
+                // we need to fix them up, which we'll do outside this lock.
+            } else if (state == STATE_CLOSED) {
+                // Someone called "close" but the handshake hasn't been interrupted yet.
+                return;
+            }
+        }
+
+        // reset session id from the native pointer and update the
+        // appropriate cache.
+        sslSession.resetId();
+        AbstractSessionContext sessionContext =
+            (sslParameters.getUseClientMode())
+            ? sslParameters.getClientSessionContext()
+                : sslParameters.getServerSessionContext();
+        sessionContext.putSession(sslSession);
+
+        // let listeners know we are finally done
+        notifyHandshakeCompletedListeners();
+
+        synchronized (stateLock) {
+            // Now that we've fixed up our state, we can tell waiting threads that
+            // we're ready.
+            state = STATE_READY;
+            // Notify all threads waiting for the handshake to complete.
+            stateLock.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks
+    @Override
+    public void verifyCertificateChain(long[] certRefs, String authMethod)
+            throws CertificateException {
+        try {
+            X509TrustManager x509tm = sslParameters.getX509TrustManager();
+            if (x509tm == null) {
+                throw new CertificateException("No X.509 TrustManager");
+            }
+            if (certRefs == null || certRefs.length == 0) {
+                throw new SSLException("Peer sent no certificate");
+            }
+            OpenSSLX509Certificate[] peerCertChain =
+                    OpenSSLX509Certificate.createCertChain(certRefs);
+
+            byte[] ocspData = NativeCrypto.SSL_get_ocsp_response(sslNativePointer);
+            byte[] tlsSctData = NativeCrypto.SSL_get_signed_cert_timestamp_list(sslNativePointer);
+
+            // Used for verifyCertificateChain callback
+            handshakeSession = new OpenSSLSessionImpl(
+                    NativeCrypto.SSL_get1_session(sslNativePointer), null, peerCertChain, ocspData,
+                    tlsSctData, getHostnameOrIP(), getPort(), null);
+
+            boolean client = sslParameters.getUseClientMode();
+            if (client) {
+                Platform.checkServerTrusted(x509tm, peerCertChain, authMethod, this);
+            } else {
+                String authType = peerCertChain[0].getPublicKey().getAlgorithm();
+                Platform.checkClientTrusted(x509tm, peerCertChain, authType, this);
+            }
+        } catch (CertificateException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new CertificateException(e);
+        } finally {
+            // Clear this before notifying handshake completed listeners
+            handshakeSession = null;
+        }
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        checkOpen();
+
+        InputStream returnVal;
+        synchronized (stateLock) {
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed.");
+            }
+
+            if (is == null) {
+                is = new SSLInputStream();
+            }
+
+            returnVal = is;
+        }
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the input stream but
+        // all reads on it will throw.
+        waitForHandshake();
+        return returnVal;
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        checkOpen();
+
+        OutputStream returnVal;
+        synchronized (stateLock) {
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed.");
+            }
+
+            if (os == null) {
+                os = new SSLOutputStream();
+            }
+
+            returnVal = os;
+        }
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the output stream but
+        // all writes on it will throw.
+        waitForHandshake();
+        return returnVal;
+    }
+
+    private void assertReadableOrWriteableState() {
+        if (state == STATE_READY || state == STATE_READY_HANDSHAKE_CUT_THROUGH) {
+            return;
+        }
+
+        throw new AssertionError("Invalid state: " + state);
+    }
+
+    private void waitForHandshake() throws IOException {
+        startHandshake();
+
+        synchronized (stateLock) {
+            while (state != STATE_READY &&
+                    state != STATE_READY_HANDSHAKE_CUT_THROUGH &&
+                    state != STATE_CLOSED) {
+                try {
+                    stateLock.wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new IOException("Interrupted waiting for handshake", e);
+                }
+            }
+
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed");
+            }
+        }
+    }
+
+    /**
+     * This inner class provides input data stream functionality
+     * for the OpenSSL native implementation. It is used to
+     * read data received via SSL protocol.
+     */
+    private class SSLInputStream extends InputStream {
+        /**
+         * OpenSSL only lets one thread read at a time, so this is used to
+         * make sure we serialize callers of SSL_read. Thread is already
+         * expected to have completed handshaking.
+         */
+        private final Object readLock = new Object();
+
+        SSLInputStream() {
+        }
+
+        /**
+         * Reads one byte. If there is no data in the underlying buffer,
+         * this operation can block until the data will be
+         * available.
+         */
+        @Override
+        public int read() throws IOException {
+            byte[] buffer = new byte[1];
+            int result = read(buffer, 0, 1);
+            return (result != -1) ? buffer[0] & 0xff : -1;
+        }
+
+        /**
+         * Method acts as described in spec for superclass.
+         * @see java.io.InputStream#read(byte[],int,int)
+         */
+        @Override
+        public int read(byte[] buf, int offset, int byteCount) throws IOException {
+            Platform.blockGuardOnNetwork();
+
+            checkOpen();
+            ArrayUtils.checkOffsetAndCount(buf.length, offset, byteCount);
+            if (byteCount == 0) {
+                return 0;
+            }
+
+            synchronized (readLock) {
+                synchronized (stateLock) {
+                    if (state == STATE_CLOSED) {
+                        throw new SocketException("socket is closed");
+                    }
+
+                    if (DBG_STATE) assertReadableOrWriteableState();
+                }
+
+                return NativeCrypto.SSL_read(sslNativePointer, Platform.getFileDescriptor(socket),
+                        ConscryptFileDescriptorSocket.this, buf, offset, byteCount, getSoTimeout());
+            }
+        }
+
+        void awaitPendingOps() {
+            if (DBG_STATE) {
+                synchronized (stateLock) {
+                    if (state != STATE_CLOSED) throw new AssertionError("State is: " + state);
+                }
+            }
+
+            synchronized (readLock) { }
+        }
+    }
+
+    /**
+     * This inner class provides output data stream functionality
+     * for the OpenSSL native implementation. It is used to
+     * write data according to the encryption parameters given in SSL context.
+     */
+    private class SSLOutputStream extends OutputStream {
+        /**
+         * OpenSSL only lets one thread write at a time, so this is used
+         * to make sure we serialize callers of SSL_write. Thread is
+         * already expected to have completed handshaking.
+         */
+        private final Object writeLock = new Object();
+
+        SSLOutputStream() {
+        }
+
+        /**
+         * Method acts as described in spec for superclass.
+         * @see java.io.OutputStream#write(int)
+         */
+        @Override
+        public void write(int oneByte) throws IOException {
+            byte[] buffer = new byte[1];
+            buffer[0] = (byte) (oneByte & 0xff);
+            write(buffer);
+        }
+
+        /**
+         * Method acts as described in spec for superclass.
+         * @see java.io.OutputStream#write(byte[],int,int)
+         */
+        @Override
+        public void write(byte[] buf, int offset, int byteCount) throws IOException {
+            Platform.blockGuardOnNetwork();
+            checkOpen();
+            ArrayUtils.checkOffsetAndCount(buf.length, offset, byteCount);
+            if (byteCount == 0) {
+                return;
+            }
+
+            synchronized (writeLock) {
+                synchronized (stateLock) {
+                    if (state == STATE_CLOSED) {
+                        throw new SocketException("socket is closed");
+                    }
+
+                    if (DBG_STATE) assertReadableOrWriteableState();
+                }
+
+                NativeCrypto.SSL_write(sslNativePointer, Platform.getFileDescriptor(socket),
+                        ConscryptFileDescriptorSocket.this, buf, offset, byteCount,
+                        writeTimeoutMilliseconds);
+            }
+        }
+
+        void awaitPendingOps() {
+            if (DBG_STATE) {
+                synchronized (stateLock) {
+                    if (state != STATE_CLOSED) throw new AssertionError("State is: " + state);
+                }
+            }
+
+            synchronized (writeLock) {}
+        }
+    }
+
+    @Override
+    public SSLSession getSession() {
+        if (sslSession == null) {
+            boolean handshakeCompleted = false;
+            try {
+                if (isConnected()) {
+                    waitForHandshake();
+                    handshakeCompleted = true;
+                }
+            } catch (IOException e) {
+                // Fall through.
+            }
+
+            if (!handshakeCompleted) {
+                // return an invalid session with
+                // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
+                return SSLNullSession.getNullSession();
+            }
+        }
+        return Platform.wrapSSLSession(sslSession);
+    }
+
+    @Override
+    SSLSession getActiveSession() {
+        return sslSession;
+    }
+
+    @Override
+    public SSLSession getHandshakeSession() {
+        return handshakeSession;
+    }
+
+    @Override
+    public boolean getEnableSessionCreation() {
+        return sslParameters.getEnableSessionCreation();
+    }
+
+    @Override
+    public void setEnableSessionCreation(boolean flag) {
+        sslParameters.setEnableSessionCreation(flag);
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return NativeCrypto.getSupportedCipherSuites();
+    }
+
+    @Override
+    public String[] getEnabledCipherSuites() {
+        return sslParameters.getEnabledCipherSuites();
+    }
+
+    @Override
+    public void setEnabledCipherSuites(String[] suites) {
+        sslParameters.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public String[] getSupportedProtocols() {
+        return NativeCrypto.getSupportedProtocols();
+    }
+
+    @Override
+    public String[] getEnabledProtocols() {
+        return sslParameters.getEnabledProtocols();
+    }
+
+    @Override
+    public void setEnabledProtocols(String[] protocols) {
+        sslParameters.setEnabledProtocols(protocols);
+    }
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param useSessionTickets True to enable session tickets
+     */
+    @Override
+    public void setUseSessionTickets(boolean useSessionTickets) {
+        sslParameters.setUseSessionTickets(useSessionTickets);
+    }
+
+    /**
+     * This method enables Server Name Indication
+     *
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    @Override
+    public void setHostname(String hostname) {
+        sslParameters.setUseSni(hostname != null);
+        super.setHostname(hostname);
+    }
+
+    /**
+     * Enables/disables TLS Channel ID for this server socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has already
+     *         started.
+     */
+    @Override
+    public void setChannelIdEnabled(boolean enabled) {
+        if (getUseClientMode()) {
+            throw new IllegalStateException("Client mode");
+        }
+
+        synchronized (stateLock) {
+            if (state != STATE_NEW) {
+                throw new IllegalStateException(
+                        "Could not enable/disable Channel ID after the initial handshake has"
+                                + " begun.");
+            }
+        }
+        sslParameters.channelIdEnabled = enabled;
+    }
+
+    /**
+     * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
+     * handshake completes.
+     *
+     * @return channel ID or {@code null} if not available.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has not yet
+     *         completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    @Override
+    public byte[] getChannelId() throws SSLException {
+        if (getUseClientMode()) {
+            throw new IllegalStateException("Client mode");
+        }
+
+        synchronized (stateLock) {
+            if (state != STATE_READY) {
+                throw new IllegalStateException(
+                        "Channel ID is only available after handshake completes");
+            }
+        }
+        return NativeCrypto.SSL_get_tls_channel_id(sslNativePointer);
+    }
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
+     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
+     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
+     *
+     * @throws IllegalStateException if this is a server socket or if the handshake has already
+     *         started.
+     */
+    @Override
+    public void setChannelIdPrivateKey(PrivateKey privateKey) {
+        if (!getUseClientMode()) {
+            throw new IllegalStateException("Server mode");
+        }
+
+        synchronized (stateLock) {
+            if (state != STATE_NEW) {
+                throw new IllegalStateException(
+                        "Could not change Channel ID private key after the initial handshake has"
+                                + " begun.");
+            }
+        }
+
+        if (privateKey == null) {
+            sslParameters.channelIdEnabled = false;
+            channelIdPrivateKey = null;
+        } else {
+            sslParameters.channelIdEnabled = true;
+            try {
+                ECParameterSpec ecParams = null;
+                if (privateKey instanceof ECKey) {
+                    ecParams = ((ECKey) privateKey).getParams();
+                }
+                if (ecParams == null) {
+                    // Assume this is a P-256 key, as specified in the contract of this method.
+                    ecParams =
+                            OpenSSLECGroupContext.getCurveByName("prime256v1").getECParameterSpec();
+                }
+                channelIdPrivateKey =
+                        OpenSSLKey.fromECPrivateKeyForTLSStackOnly(privateKey, ecParams);
+            } catch (InvalidKeyException e) {
+                // Will have error in startHandshake
+            }
+        }
+    }
+
+    @Override
+    public boolean getUseClientMode() {
+        return sslParameters.getUseClientMode();
+    }
+
+    @Override
+    public void setUseClientMode(boolean mode) {
+        synchronized (stateLock) {
+            if (state != STATE_NEW) {
+                throw new IllegalArgumentException(
+                        "Could not change the mode after the initial handshake has begun.");
+            }
+        }
+        sslParameters.setUseClientMode(mode);
+    }
+
+    @Override
+    public boolean getWantClientAuth() {
+        return sslParameters.getWantClientAuth();
+    }
+
+    @Override
+    public boolean getNeedClientAuth() {
+        return sslParameters.getNeedClientAuth();
+    }
+
+    @Override
+    public void setNeedClientAuth(boolean need) {
+        sslParameters.setNeedClientAuth(need);
+    }
+
+    @Override
+    public void setWantClientAuth(boolean want) {
+        sslParameters.setWantClientAuth(want);
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    @Override
+    public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+        this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
+
+        Platform.setSocketWriteTimeout(this, writeTimeoutMilliseconds);
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    @Override
+    public int getSoWriteTimeout() throws SocketException {
+        return writeTimeoutMilliseconds;
+    }
+
+    /**
+     * Set the handshake timeout on this socket.  This timeout is specified in
+     * milliseconds and will be used only during the handshake process.
+     */
+    @Override
+    public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+        this.handshakeTimeoutMilliseconds = handshakeTimeoutMilliseconds;
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void close() throws IOException {
+        // TODO: Close SSL sockets using a background thread so they close gracefully.
+
+        SSLInputStream sslInputStream;
+        SSLOutputStream sslOutputStream;
+
+        synchronized (stateLock) {
+            if (state == STATE_CLOSED) {
+                // close() has already been called, so do nothing and return.
+                return;
+            }
+
+            int oldState = state;
+            state = STATE_CLOSED;
+
+            if (oldState == STATE_NEW) {
+                // The handshake hasn't been started yet, so there's no OpenSSL related
+                // state to clean up. We still need to close the underlying socket if
+                // we're wrapping it and were asked to autoClose.
+                closeUnderlyingSocket();
+
+                stateLock.notifyAll();
+                return;
+            }
+
+            if (oldState != STATE_READY && oldState != STATE_READY_HANDSHAKE_CUT_THROUGH) {
+                // If we're in these states, we still haven't returned from startHandshake.
+                // We call SSL_interrupt so that we can interrupt SSL_do_handshake and then
+                // set the state to STATE_CLOSED. startHandshake will handle all cleanup
+                // after SSL_do_handshake returns, so we don't have anything to do here.
+                NativeCrypto.SSL_interrupt(sslNativePointer);
+
+                stateLock.notifyAll();
+                return;
+            }
+
+            stateLock.notifyAll();
+            // We've already returned from startHandshake, so we potentially have
+            // input and output streams to clean up.
+            sslInputStream = is;
+            sslOutputStream = os;
+        }
+
+        // Don't bother interrupting unless we have something to interrupt.
+        if (sslInputStream != null || sslOutputStream != null) {
+            NativeCrypto.SSL_interrupt(sslNativePointer);
+        }
+
+        // Wait for the input and output streams to finish any reads they have in
+        // progress. If there are no reads in progress at this point, future reads will
+        // throw because state == STATE_CLOSED
+        if (sslInputStream != null) {
+            sslInputStream.awaitPendingOps();
+        }
+        if (sslOutputStream != null) {
+            sslOutputStream.awaitPendingOps();
+        }
+
+        shutdownAndFreeSslNative();
+    }
+
+    private void shutdownAndFreeSslNative() throws IOException {
+        try {
+            Platform.blockGuardOnNetwork();
+            NativeCrypto.SSL_shutdown(sslNativePointer, Platform.getFileDescriptor(socket),
+                    this);
+        } catch (IOException ignored) {
+            /*
+             * Note that although close() can throw
+             * IOException, the RI does not throw if there
+             * is problem sending a "close notify" which
+             * can happen if the underlying socket is closed.
+             */
+        } finally {
+            free();
+            closeUnderlyingSocket();
+        }
+    }
+
+    private void closeUnderlyingSocket() throws IOException {
+        super.close();
+    }
+
+    private void free() {
+        if (sslNativePointer == 0) {
+            return;
+        }
+        NativeCrypto.SSL_free(sslNativePointer);
+        sslNativePointer = 0;
+        Platform.closeGuardClose(guard);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            /*
+             * Just worry about our own state. Notably we do not try and
+             * close anything. The SocketImpl, either our own
+             * PlainSocketImpl, or the Socket we are wrapping, will do
+             * that. This might mean we do not properly SSL_shutdown, but
+             * if you want to do that, properly close the socket yourself.
+             *
+             * The reason why we don't try to SSL_shutdown, is that there
+             * can be a race between finalizers where the PlainSocketImpl
+             * finalizer runs first and closes the socket. However, in the
+             * meanwhile, the underlying file descriptor could be reused
+             * for another purpose. If we call SSL_shutdown, the
+             * underlying socket BIOs still have the old file descriptor
+             * and will write the close notify to some unsuspecting
+             * reader.
+             */
+            if (guard != null) {
+                Platform.closeGuardWarnIfOpen(guard);
+            }
+            free();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Returns the protocol agreed upon by client and server, or {@code null} if
+     * no protocol was agreed upon.
+     */
+    @Override
+    public byte[] getAlpnSelectedProtocol() {
+        return NativeCrypto.SSL_get0_alpn_selected(sslNativePointer);
+    }
+
+    /**
+     * Sets the list of ALPN protocols. This method internally converts the protocols to their
+     * wire-format form.
+     *
+     * @param alpnProtocols the list of ALPN protocols
+     * @see #setAlpnProtocols(byte[])
+     */
+    @Override
+    public void setAlpnProtocols(String[] alpnProtocols) {
+        sslParameters.setAlpnProtocols(alpnProtocols);
+    }
+
+    /**
+     * Alternate version of {@link #setAlpnProtocols(String[])} that directly sets the list of
+     * ALPN in the wire-format form used by BoringSSL (length-prefixed 8-bit strings).
+     * Requires that all strings be encoded with US-ASCII.
+     *
+     * @param alpnProtocols the encoded form of the ALPN protocol list
+     * @see #setAlpnProtocols(String[])
+     */
+    @Override
+    public void setAlpnProtocols(byte[] alpnProtocols) {
+        sslParameters.setAlpnProtocols(alpnProtocols);
+    }
+
+    @Override
+    public SSLParameters getSSLParameters() {
+        SSLParameters params = super.getSSLParameters();
+        Platform.getSSLParameters(params, sslParameters, this);
+        return params;
+    }
+
+    @Override
+    public void setSSLParameters(SSLParameters p) {
+        super.setSSLParameters(p);
+        Platform.setSSLParameters(p, sslParameters, this);
+    }
+
+    @Override
+    public String chooseServerAlias(X509KeyManager keyManager, String keyType) {
+        return keyManager.chooseServerAlias(keyType, null, this);
+    }
+
+    @Override
+    public String chooseClientAlias(X509KeyManager keyManager, X500Principal[] issuers,
+            String[] keyTypes) {
+        return keyManager.chooseClientAlias(keyTypes, null, this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public String chooseServerPSKIdentityHint(PSKKeyManager keyManager) {
+        return keyManager.chooseServerKeyIdentityHint(this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) {
+        return keyManager.chooseClientKeyIdentity(identityHint, this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) {
+        return keyManager.getKey(identityHint, identity, this);
+    }
+}
diff --git a/common/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java b/common/src/main/java/org/conscrypt/ConscryptServerSocket.java
similarity index 82%
rename from common/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java
rename to common/src/main/java/org/conscrypt/ConscryptServerSocket.java
index a7e3654..80a758f 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java
+++ b/common/src/main/java/org/conscrypt/ConscryptServerSocket.java
@@ -19,32 +19,33 @@
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
+import javax.net.ssl.SSLServerSocket;
 
 /**
  * BoringSSL-based implementation of server sockets.
  */
-final class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
+final class ConscryptServerSocket extends SSLServerSocket {
     private final SSLParametersImpl sslParameters;
     private boolean channelIdEnabled;
     private boolean useEngineSocket;
 
-    OpenSSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
+    ConscryptServerSocket(SSLParametersImpl sslParameters) throws IOException {
         this.sslParameters = sslParameters;
     }
 
-    OpenSSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
+    ConscryptServerSocket(int port, SSLParametersImpl sslParameters)
         throws IOException {
         super(port);
         this.sslParameters = sslParameters;
     }
 
-    OpenSSLServerSocketImpl(int port, int backlog, SSLParametersImpl sslParameters)
+    ConscryptServerSocket(int port, int backlog, SSLParametersImpl sslParameters)
         throws IOException {
         super(port, backlog);
         this.sslParameters = sslParameters;
     }
 
-    OpenSSLServerSocketImpl(int port,
+    ConscryptServerSocket(int port,
                                       int backlog,
                                       InetAddress iAddress,
                                       SSLParametersImpl sslParameters)
@@ -56,7 +57,7 @@
     /**
      * Configures the socket to be created for this instance.
      */
-    OpenSSLServerSocketImpl setUseEngineSocket(boolean useEngineSocket) {
+    ConscryptServerSocket setUseEngineSocket(boolean useEngineSocket) {
         this.useEngineSocket = useEngineSocket;
         return this;
     }
@@ -174,21 +175,15 @@
 
     @Override
     public Socket accept() throws IOException {
+        final AbstractConscryptSocket socket;
         if (useEngineSocket) {
-            Socket rawSocket = new Socket();
-            implAccept(rawSocket);
-
-            // Enable channel ID.
-            OpenSSLEngineSocketImpl socket =
-                    new OpenSSLEngineSocketImpl(rawSocket, null, -1, true, sslParameters);
-            socket.setChannelIdEnabled(channelIdEnabled);
-            socket.startHandshake();
-            return socket;
+            socket = new ConscryptEngineSocket(sslParameters);
         } else {
-            OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters);
-            socket.setChannelIdEnabled(channelIdEnabled);
-            implAccept(socket);
-            return socket;
+            socket = new ConscryptFileDescriptorSocket(sslParameters);
         }
+
+        socket.setChannelIdEnabled(channelIdEnabled);
+        implAccept(socket);
+        return socket;
     }
 }
diff --git a/common/src/main/java/org/conscrypt/OpenSSLEngineSocketImpl.java b/common/src/main/java/org/conscrypt/OpenSSLEngineSocketImpl.java
deleted file mode 100644
index 2a379d2..0000000
--- a/common/src/main/java/org/conscrypt/OpenSSLEngineSocketImpl.java
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright 2016 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 org.conscrypt;
-
-import static javax.net.ssl.SSLEngineResult.Status.OK;
-
-import java.io.EOFException;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.security.PrivateKey;
-import java.security.cert.CertificateException;
-import javax.crypto.SecretKey;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.X509KeyManager;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Implements crypto handling by delegating to {@link ConscryptEngine}. Used for socket
- * implementations that are not backed by a real OS socket.
- */
-final class OpenSSLEngineSocketImpl extends OpenSSLSocketImplWrapper {
-    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
-
-    private final ConscryptEngine engine;
-    private final Socket socket;
-    private final OutputStreamWrapper outputStreamWrapper;
-    private final InputStreamWrapper inputStreamWrapper;
-    private boolean handshakeComplete;
-
-    OpenSSLEngineSocketImpl(SSLParametersImpl sslParameters) throws IOException {
-        this(new Socket(), null, -1, false, sslParameters);
-    }
-
-    OpenSSLEngineSocketImpl(String host, int port, SSLParametersImpl sslParameters)
-            throws IOException {
-        this(new Socket(host, port), host, port, false, sslParameters);
-    }
-
-    OpenSSLEngineSocketImpl(String host, int port, InetAddress clientAddress, int clientPort,
-            SSLParametersImpl sslParameters) throws IOException {
-        this(new Socket(host, port, clientAddress, clientPort), host, port, false, sslParameters);
-    }
-
-    OpenSSLEngineSocketImpl(InetAddress address, int port, SSLParametersImpl sslParameters)
-            throws IOException {
-        this(new Socket(address, port), null, port, false, sslParameters);
-    }
-
-    OpenSSLEngineSocketImpl(InetAddress address, int port, InetAddress clientAddress,
-            int clientPort, SSLParametersImpl sslParameters) throws IOException {
-        this(new Socket(address, port, clientAddress, clientPort), null, port, false,
-                sslParameters);
-    }
-
-    OpenSSLEngineSocketImpl(Socket socket, String hostname, int port, boolean autoClose,
-            SSLParametersImpl sslParameters) throws IOException {
-        super(socket, hostname, port, autoClose, sslParameters);
-        this.socket = socket;
-        engine = new ConscryptEngine(hostname, port, sslParameters);
-
-        // When the handshake completes, notify any listeners.
-        engine.setHandshakeListener(new HandshakeListener() {
-            @Override
-            public void onHandshakeFinished() {
-                if (!handshakeComplete) {
-                    handshakeComplete = true;
-                    OpenSSLEngineSocketImpl.this.notifyHandshakeCompletedListeners();
-                }
-            }
-        });
-        outputStreamWrapper = new OutputStreamWrapper();
-        inputStreamWrapper = new InputStreamWrapper();
-        engine.setUseClientMode(sslParameters.getUseClientMode());
-    }
-
-    @Override
-    public void startHandshake() throws IOException {
-        try {
-            // Trigger the handshake
-            boolean beginHandshakeCalled = false;
-            while (!handshakeComplete) {
-                switch (engine.getHandshakeStatus()) {
-                    case NOT_HANDSHAKING: {
-                        if (!beginHandshakeCalled) {
-                            beginHandshakeCalled = true;
-                            engine.beginHandshake();
-                            break;
-                        }
-                        break;
-                    }
-                    case FINISHED: {
-                        return;
-                    }
-                    case NEED_WRAP: {
-                        outputStreamWrapper.write(EMPTY_BUFFER);
-                        break;
-                    }
-                    case NEED_UNWRAP: {
-                        if (inputStreamWrapper.read(EmptyArray.BYTE) == -1) {
-                            // Can't complete the handshake due to EOF.
-                            throw SSLUtils.toSSLHandshakeException(new EOFException());
-                        }
-                        break;
-                    }
-                    case NEED_TASK: {
-                        throw new IllegalStateException("ConscryptEngine returned NEED_TASK");
-                    }
-                    default: { break; }
-                }
-            }
-        } catch (Exception e) {
-            close();
-            throw SSLUtils.toSSLHandshakeException(e);
-        }
-    }
-
-    @Override
-    public void onSSLStateChange(int type, int val) {
-        throw new AssertionError("Should be handled by engine");
-    }
-
-    @Override
-    public void verifyCertificateChain(long[] certRefs, String authMethod)
-            throws CertificateException {
-        throw new AssertionError("Should be handled by engine");
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        return inputStreamWrapper;
-    }
-
-    @Override
-    public OutputStream getOutputStream() throws IOException {
-        return outputStreamWrapper;
-    }
-
-    @Override
-    public SSLSession getSession() {
-        return engine.getSession();
-    }
-
-    @Override
-    public boolean getEnableSessionCreation() {
-        return super.getEnableSessionCreation();
-    }
-
-    @Override
-    public void setEnableSessionCreation(boolean flag) {
-        super.setEnableSessionCreation(flag);
-    }
-
-    @Override
-    public String[] getSupportedCipherSuites() {
-        return super.getSupportedCipherSuites();
-    }
-
-    @Override
-    public String[] getEnabledCipherSuites() {
-        return super.getEnabledCipherSuites();
-    }
-
-    @Override
-    public void setEnabledCipherSuites(String[] suites) {
-        super.setEnabledCipherSuites(suites);
-    }
-
-    @Override
-    public String[] getSupportedProtocols() {
-        return super.getSupportedProtocols();
-    }
-
-    @Override
-    public String[] getEnabledProtocols() {
-        return super.getEnabledProtocols();
-    }
-
-    @Override
-    public void setEnabledProtocols(String[] protocols) {
-        super.setEnabledProtocols(protocols);
-    }
-
-    @Override
-    public void setUseSessionTickets(boolean useSessionTickets) {
-        super.setUseSessionTickets(useSessionTickets);
-    }
-
-    @Override
-    public void setHostname(String hostname) {
-        super.setHostname(hostname);
-    }
-
-    @Override
-    public void setChannelIdEnabled(boolean enabled) {
-        super.setChannelIdEnabled(enabled);
-    }
-
-    @Override
-    public byte[] getChannelId() throws SSLException {
-        return super.getChannelId();
-    }
-
-    @Override
-    public void setChannelIdPrivateKey(PrivateKey privateKey) {
-        super.setChannelIdPrivateKey(privateKey);
-    }
-
-    @Override
-    public boolean getUseClientMode() {
-        return super.getUseClientMode();
-    }
-
-    @Override
-    public void setUseClientMode(boolean mode) {
-        engine.setUseClientMode(mode);
-    }
-
-    @Override
-    public boolean getWantClientAuth() {
-        return super.getWantClientAuth();
-    }
-
-    @Override
-    public boolean getNeedClientAuth() {
-        return super.getNeedClientAuth();
-    }
-
-    @Override
-    public void setNeedClientAuth(boolean need) {
-        super.setNeedClientAuth(need);
-    }
-
-    @Override
-    public void setWantClientAuth(boolean want) {
-        super.setWantClientAuth(want);
-    }
-
-    @Override
-    public void sendUrgentData(int data) throws IOException {
-        super.sendUrgentData(data);
-    }
-
-    @Override
-    public void setOOBInline(boolean on) throws SocketException {
-        super.setOOBInline(on);
-    }
-
-    @Override
-    public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
-        throw new UnsupportedOperationException("Not supported");
-    }
-
-    @Override
-    public int getSoWriteTimeout() throws SocketException {
-        return 0;
-    }
-
-    @Override
-    public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
-        throw new UnsupportedOperationException("Not supported");
-    }
-
-    @Override
-    public synchronized void close() throws IOException {
-        // Closing Socket.
-        engine.closeInbound();
-        engine.closeOutbound();
-        socket.close();
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        super.finalize();
-    }
-
-    @Override
-    public SocketChannel getChannel() {
-        return super.getChannel();
-    }
-
-    @Override
-    public FileDescriptor getFileDescriptor$() {
-        throw new UnsupportedOperationException("Not supported");
-    }
-
-    @Override
-    public byte[] getNpnSelectedProtocol() {
-        return null;
-    }
-
-    @Override
-    public byte[] getAlpnSelectedProtocol() {
-        return engine.getAlpnSelectedProtocol();
-    }
-
-    @Override
-    public void setNpnProtocols(byte[] npnProtocols) {
-        super.setNpnProtocols(npnProtocols);
-    }
-
-    @Override
-    public void setAlpnProtocols(byte[] alpnProtocols) {
-        super.setAlpnProtocols(alpnProtocols);
-    }
-
-    @Override
-    public String chooseServerAlias(X509KeyManager keyManager, String keyType) {
-        return engine.chooseServerAlias(keyManager, keyType);
-    }
-
-    @Override
-    public String chooseClientAlias(
-            X509KeyManager keyManager, X500Principal[] issuers, String[] keyTypes) {
-        return engine.chooseClientAlias(keyManager, issuers, keyTypes);
-    }
-
-    @Override
-    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
-    public String chooseServerPSKIdentityHint(PSKKeyManager keyManager) {
-        return engine.chooseServerPSKIdentityHint(keyManager);
-    }
-
-    @Override
-    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
-    public String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) {
-        return engine.chooseClientPSKIdentity(keyManager, identityHint);
-    }
-
-    @Override
-    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
-    public SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) {
-        return engine.getPSKKey(keyManager, identityHint, identity);
-    }
-
-    /**
-     * Wrap bytes written to the underlying socket.
-     */
-    private final class OutputStreamWrapper extends OutputStream {
-        private final Object stateLock = new Object();
-        private ByteBuffer target;
-        private OutputStream socketOutputStream;
-        private SocketChannel socketChannel;
-
-        OutputStreamWrapper() {}
-
-        @Override
-        public void write(int b) throws IOException {
-            write(new byte[] {(byte) b});
-        }
-
-        @Override
-        public void write(byte[] b) throws IOException {
-            write(ByteBuffer.wrap(b));
-        }
-
-        @Override
-        public void write(byte[] b, int off, int len) throws IOException {
-            write(ByteBuffer.wrap(b, off, len));
-        }
-
-        private void write(ByteBuffer buffer) throws IOException {
-            synchronized (stateLock) {
-                try {
-                    init();
-
-                    // Need to loop through at least once to enable handshaking where no application
-                    // bytes are
-                    // processed.
-                    int len = buffer.remaining();
-                    SSLEngineResult engineResult;
-                    do {
-                        target.clear();
-                        engineResult = engine.wrap(buffer, target);
-                        if (engineResult.getStatus() != OK) {
-                            throw new SSLException(
-                                    "Unexpected engine result " + engineResult.getStatus());
-                        }
-                        if (target.position() != engineResult.bytesProduced()) {
-                            throw new SSLException("Engine bytesProduced "
-                                    + engineResult.bytesProduced()
-                                    + " does not match bytes written " + target.position());
-                        }
-                        len -= engineResult.bytesConsumed();
-                        if (len != buffer.remaining()) {
-                            throw new SSLException(
-                                    "Engine did not read the correct number of bytes");
-                        }
-
-                        target.flip();
-
-                        // Write the data to the socket.
-                        if (socketChannel != null) {
-                            // Loop until all of the data is written to the channel. Typically,
-                            // SocketChannel writes will return only after all bytes are written,
-                            // so we won't really loop here.
-                            while (target.hasRemaining()) {
-                                socketChannel.write(target);
-                            }
-                        } else {
-                            // Target is a heap buffer.
-                            socketOutputStream.write(target.array(), 0, target.limit());
-                        }
-                    } while (len > 0);
-                } catch (IOException e) {
-                    throw e;
-                } catch (RuntimeException e) {
-                    throw e;
-                }
-            }
-        }
-
-        @Override
-        public void flush() throws IOException {
-            synchronized (stateLock) {
-                init();
-                socketOutputStream.flush();
-            }
-        }
-
-        @Override
-        public void close() throws IOException {
-            socket.close();
-        }
-
-        private void init() throws IOException {
-            if (socketOutputStream == null) {
-                socketOutputStream = socket.getOutputStream();
-                socketChannel = socket.getChannel();
-                if (socketChannel != null) {
-                    // Optimization. Using direct buffers wherever possible to avoid passing
-                    // arrays to JNI.
-                    target = ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize());
-                } else {
-                    target = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
-                }
-            }
-        }
-    }
-
-    /**
-     * Unwrap bytes read from the underlying socket.
-     */
-    private final class InputStreamWrapper extends InputStream {
-        private final Object stateLock = new Object();
-        private final byte[] singleByte = new byte[1];
-        private final ByteBuffer fromEngine;
-        private ByteBuffer fromSocket;
-        private InputStream socketInputStream;
-        private SocketChannel socketChannel;
-
-        InputStreamWrapper() {
-            fromEngine = ByteBuffer.allocateDirect(engine.getSession().getApplicationBufferSize());
-            // Initially fromEngine.remaining() == 0.
-            fromEngine.flip();
-        }
-
-        @Override
-        public int read() throws IOException {
-            synchronized (stateLock) {
-                // Handle returning of -1 if EOF is reached.
-                int count = read(singleByte, 0, 1);
-                if (count == -1) {
-                    // Handle EOF.
-                    return -1;
-                }
-                if (count != 1) {
-                    throw new SSLException("read incorrect number of bytes " + count);
-                }
-                return (int) singleByte[0];
-            }
-        }
-
-        @Override
-        public int read(byte[] b) throws IOException {
-            return read(b, 0, b.length);
-        }
-
-        @Override
-        public int read(byte[] b, int off, int len) throws IOException {
-            synchronized (stateLock) {
-                try {
-                    // Make sure the input stream has been created.
-                    init();
-
-                    for (;;) {
-                        // Serve any remaining data from the engine first.
-                        if (fromEngine.remaining() > 0) {
-                            int readFromEngine = Math.min(fromEngine.remaining(), len);
-                            fromEngine.get(b, off, readFromEngine);
-                            return readFromEngine;
-                        }
-
-                        // Try to unwrap any data already in the socket buffer.
-                        boolean needMoreData = true;
-                        if (fromSocket.position() > 0) {
-                            // Unwrap the unencrypted bytes into the engine buffer.
-                            fromSocket.flip();
-                            fromEngine.clear();
-                            SSLEngineResult engineResult = engine.unwrap(fromSocket, fromEngine);
-
-                            // Shift any remaining data to the beginning of the buffer so that
-                            // we can accommodate the next full packet. After this is called,
-                            // limit will be restored to capacity and position will point just
-                            // past the end of the data.
-                            fromSocket.compact();
-                            fromEngine.flip();
-
-                            switch (engineResult.getStatus()) {
-                                case BUFFER_UNDERFLOW: {
-                                    if (engineResult.bytesProduced() == 0) {
-                                        // Need to read more data from the socket.
-                                        break;
-                                    }
-                                    // Also serve the data that was produced.
-                                    needMoreData = false;
-                                    break;
-                                }
-                                case OK: {
-                                    // We processed the entire packet successfully.
-                                    needMoreData = false;
-                                    break;
-                                }
-                                case CLOSED: {
-                                    // EOF
-                                    return -1;
-                                }
-                                default: {
-                                    // Anything else is an error.
-                                    throw new SSLException(
-                                            "Unexpected engine result " + engineResult.getStatus());
-                                }
-                            }
-
-                            if (!needMoreData && engineResult.bytesProduced() == 0) {
-                                // Read successfully, but produced no data. Possibly part of a
-                                // handshake.
-                                return 0;
-                            }
-                        }
-
-                        // Read more data from the socket.
-                        if (needMoreData && readFromSocket() == -1) {
-                            // Failed to read the next encrypted packet before reaching EOF.
-                            return -1;
-                        }
-
-                        // Continue the loop and return the data from the engine buffer.
-                    }
-                } catch (IOException e) {
-                    throw e;
-                } catch (RuntimeException e) {
-                    throw e;
-                }
-            }
-        }
-
-        private void init() throws IOException {
-            if (socketInputStream == null) {
-                socketInputStream = socket.getInputStream();
-                socketChannel = socket.getChannel();
-                if (socketChannel != null) {
-                    fromSocket =
-                            ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize());
-                } else {
-                    fromSocket = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
-                }
-            }
-        }
-
-        private int readFromSocket() throws IOException {
-            if (socketChannel != null) {
-                return socketChannel.read(fromSocket);
-            }
-            // Read directly to the underlying array and increment the buffer position if
-            // appropriate.
-            int read = socketInputStream.read(
-                    fromSocket.array(), fromSocket.position(), fromSocket.remaining());
-            if (read > 0) {
-                fromSocket.position(fromSocket.position() + read);
-            }
-            return read;
-        }
-    }
-}
diff --git a/common/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java b/common/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
index 008e92f..c2507d8 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
@@ -24,6 +24,9 @@
 
 /**
  * An implementation of {@link SSLServerSocketFactory} using BoringSSL.
+ *
+ * <p/>This name of this class cannot change in order to maintain backward-compatibility with GMS
+ * core {@code ProviderInstallerImpl}
  */
 final class OpenSSLServerSocketFactoryImpl extends SSLServerSocketFactory {
     private static boolean useEngineSocketByDefault = SSLUtils.USE_ENGINE_SOCKET_BY_DEFAULT;
@@ -37,8 +40,7 @@
             this.sslParameters = SSLParametersImpl.getDefault();
             this.sslParameters.setUseClientMode(false);
         } catch (KeyManagementException e) {
-            instantiationException =
-                new IOException("Delayed instantiation exception:");
+            instantiationException = new IOException("Delayed instantiation exception:");
             instantiationException.initCause(e);
         }
     }
@@ -75,26 +77,26 @@
 
     @Override
     public ServerSocket createServerSocket() throws IOException {
-        return new OpenSSLServerSocketImpl((SSLParametersImpl) sslParameters.clone())
+        return new ConscryptServerSocket((SSLParametersImpl) sslParameters.clone())
                 .setUseEngineSocket(useEngineSocket);
     }
 
     @Override
     public ServerSocket createServerSocket(int port) throws IOException {
-        return new OpenSSLServerSocketImpl(port, (SSLParametersImpl) sslParameters.clone())
+        return new ConscryptServerSocket(port, (SSLParametersImpl) sslParameters.clone())
                 .setUseEngineSocket(useEngineSocket);
     }
 
     @Override
     public ServerSocket createServerSocket(int port, int backlog) throws IOException {
-        return new OpenSSLServerSocketImpl(port, backlog, (SSLParametersImpl) sslParameters.clone())
+        return new ConscryptServerSocket(port, backlog, (SSLParametersImpl) sslParameters.clone())
                 .setUseEngineSocket(useEngineSocket);
     }
 
     @Override
     public ServerSocket createServerSocket(int port, int backlog, InetAddress iAddress)
             throws IOException {
-        return new OpenSSLServerSocketImpl(
+        return new ConscryptServerSocket(
                 port, backlog, iAddress, (SSLParametersImpl) sslParameters.clone())
                 .setUseEngineSocket(useEngineSocket);
     }
diff --git a/common/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java b/common/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
index 1794d9b..3236caf 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
@@ -19,12 +19,16 @@
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
+import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.security.KeyManagementException;
 import javax.net.ssl.SSLSocketFactory;
 
 /**
  * An implementation of {@link SSLSocketFactory} based on BoringSSL.
+ *
+ * <p/>This name of this class cannot change in order to maintain backward-compatibility with GMS
+ * core {@code ProviderInstallerImpl}
  */
 final class OpenSSLSocketFactoryImpl extends SSLSocketFactory {
     private static boolean useEngineSocketByDefault = SSLUtils.USE_ENGINE_SOCKET_BY_DEFAULT;
@@ -81,18 +85,20 @@
             throw instantiationException;
         }
         if (useEngineSocket) {
-            return new OpenSSLEngineSocketImpl((SSLParametersImpl) sslParameters.clone());
+            return new ConscryptEngineSocket((SSLParametersImpl) sslParameters.clone());
         } else {
-            return new OpenSSLSocketImpl((SSLParametersImpl) sslParameters.clone());
+            return new ConscryptFileDescriptorSocket((SSLParametersImpl) sslParameters.clone());
         }
     }
 
     @Override
     public Socket createSocket(String hostname, int port) throws IOException, UnknownHostException {
         if (useEngineSocket) {
-            return new OpenSSLEngineSocketImpl(hostname, port, (SSLParametersImpl) sslParameters.clone());
+            return new ConscryptEngineSocket(
+                    hostname, port, (SSLParametersImpl) sslParameters.clone());
         } else {
-            return new OpenSSLSocketImpl(hostname, port, (SSLParametersImpl) sslParameters.clone());
+            return new ConscryptFileDescriptorSocket(
+                    hostname, port, (SSLParametersImpl) sslParameters.clone());
         }
     }
 
@@ -100,16 +106,10 @@
     public Socket createSocket(String hostname, int port, InetAddress localHost, int localPort)
             throws IOException, UnknownHostException {
         if (useEngineSocket) {
-            return new OpenSSLEngineSocketImpl(hostname,
-                    port,
-                    localHost,
-                    localPort,
+            return new ConscryptEngineSocket(hostname, port, localHost, localPort,
                     (SSLParametersImpl) sslParameters.clone());
         } else {
-            return new OpenSSLSocketImpl(hostname,
-                    port,
-                    localHost,
-                    localPort,
+            return new ConscryptFileDescriptorSocket(hostname, port, localHost, localPort,
                     (SSLParametersImpl) sslParameters.clone());
         }
     }
@@ -117,48 +117,46 @@
     @Override
     public Socket createSocket(InetAddress address, int port) throws IOException {
         if (useEngineSocket) {
-            return new OpenSSLEngineSocketImpl(address, port, (SSLParametersImpl) sslParameters.clone());
+            return new ConscryptEngineSocket(
+                    address, port, (SSLParametersImpl) sslParameters.clone());
         } else {
-            return new OpenSSLSocketImpl(address, port, (SSLParametersImpl) sslParameters.clone());
+            return new ConscryptFileDescriptorSocket(
+                    address, port, (SSLParametersImpl) sslParameters.clone());
         }
     }
 
     @Override
-    public Socket createSocket(InetAddress address,
-                               int port,
-                               InetAddress localAddress,
-                               int localPort)
-            throws IOException {
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+            int localPort) throws IOException {
         if (useEngineSocket) {
-            return new OpenSSLEngineSocketImpl(address,
-                    port,
-                    localAddress,
-                    localPort,
+            return new ConscryptEngineSocket(address, port, localAddress, localPort,
                     (SSLParametersImpl) sslParameters.clone());
         } else {
-            return new OpenSSLSocketImpl(address,
-                    port,
-                    localAddress,
-                    localPort,
+            return new ConscryptFileDescriptorSocket(address, port, localAddress, localPort,
                     (SSLParametersImpl) sslParameters.clone());
         }
     }
 
     @Override
-    public Socket createSocket(Socket s, String hostname, int port, boolean autoClose)
+    public Socket createSocket(Socket socket, String hostname, int port, boolean autoClose)
             throws IOException {
-        if (hasFileDescriptor(s) && !useEngineSocket) {
-            return new OpenSSLSocketImplWrapper(
-                    s, hostname, port, autoClose, (SSLParametersImpl) sslParameters.clone());
+        Preconditions.checkNotNull(socket, "socket");
+        if (!socket.isConnected()) {
+            throw new SocketException("Socket is not connected.");
+        }
+
+        if (hasFileDescriptor(socket) && !useEngineSocket) {
+            return new ConscryptFileDescriptorSocket(
+                    socket, hostname, port, autoClose, (SSLParametersImpl) sslParameters.clone());
         } else {
-            return new OpenSSLEngineSocketImpl(
-                    s, hostname, port, autoClose, (SSLParametersImpl) sslParameters.clone());
+            return new ConscryptEngineSocket(
+                    socket, hostname, port, autoClose, (SSLParametersImpl) sslParameters.clone());
         }
     }
 
     private boolean hasFileDescriptor(Socket s) {
         try {
-            // If socket has a file descriptor we can use OpenSSLSocketImplWrapper directly
+            // If socket has a file descriptor we can use it directly
             // otherwise we need to use the engine.
             Platform.getFileDescriptor(s);
             return true;
diff --git a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
index 60f6dd3..b33f9e2 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
@@ -16,1299 +16,116 @@
 
 package org.conscrypt;
 
-import static org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED;
-import static org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_COMPLETED;
-import static org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_STARTED;
-import static org.conscrypt.SSLUtils.EngineStates.STATE_NEW;
-import static org.conscrypt.SSLUtils.EngineStates.STATE_READY;
-import static org.conscrypt.SSLUtils.EngineStates.STATE_READY_HANDSHAKE_CUT_THROUGH;
-
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.net.InetAddress;
-import java.net.InetSocketAddress;
 import java.net.Socket;
-import java.net.SocketAddress;
 import java.net.SocketException;
-import java.security.InvalidKeyException;
 import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.interfaces.ECKey;
-import java.security.spec.ECParameterSpec;
-import java.util.ArrayList;
-import javax.crypto.SecretKey;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
 import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLProtocolException;
 import javax.net.ssl.SSLSession;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
 
 /**
- * Implementation of the class OpenSSLSocketImpl based on OpenSSL.
- * <p>
- * Extensions to SSLSocket include:
- * <ul>
- * <li>handshake timeout
- * <li>session tickets
- * <li>Server Name Indication
- * </ul>
+ * Public shim allowing us to stay backward-compatible with legacy applications which were using
+ * Conscrypt's extended socket API before the introduction of the {@link Conscrypt} class.
  *
  * @hide
  */
 @Internal
-public class OpenSSLSocketImpl
-        extends javax.net.ssl.SSLSocket
-        implements NativeCrypto.SSLHandshakeCallbacks, SSLParametersImpl.AliasChooser,
-        SSLParametersImpl.PSKCallbacks {
-
-    private static final boolean DBG_STATE = false;
-
-    /**
-     * Protects handshakeStarted and handshakeCompleted.
-     */
-    private final Object stateLock = new Object();
-
-
-    // @GuardedBy("stateLock");
-    private int state = STATE_NEW;
-
-    /**
-     * Protected by synchronizing on stateLock. Starts as 0, set by
-     * startHandshake, reset to 0 on close.
-     */
-    // @GuardedBy("stateLock");
-    private long sslNativePointer;
-
-    /**
-     * Protected by synchronizing on stateLock. Starts as null, set by
-     * getInputStream.
-     */
-    // @GuardedBy("stateLock");
-    private SSLInputStream is;
-
-    /**
-     * Protected by synchronizing on stateLock. Starts as null, set by
-     * getInputStream.
-     */
-    // @GuardedBy("stateLock");
-    private SSLOutputStream os;
-
-    private final Socket socket;
-    private final boolean autoClose;
-
-    /**
-     * The peer's DNS hostname if it was supplied during creation. Note that
-     * this may be a raw IP address, so it should be checked before use with
-     * extensions that don't use it like Server Name Indication (SNI).
-     */
-    private String peerHostname;
-
-    /**
-     * The peer's port if it was supplied during creation. Should only be set if
-     * {@link #peerHostname} is also set.
-     */
-    private final int peerPort;
-
-    private final SSLParametersImpl sslParameters;
-
-    /*
-     * A CloseGuard object on Android. On other platforms, this is nothing.
-     */
-    private final Object guard = Platform.closeGuardGet();
-
-    private ArrayList<HandshakeCompletedListener> listeners;
-
-    /**
-     * Private key for the TLS Channel ID extension. This field is client-side
-     * only. Set during startHandshake.
-     */
-    private OpenSSLKey channelIdPrivateKey;
-
-    /** Set during startHandshake. */
-    private AbstractOpenSSLSession sslSession;
-
-    /** Used during handshake callbacks. */
-    private AbstractOpenSSLSession handshakeSession;
-
-    /**
-     * Local cache of timeout to avoid getsockopt on every read and
-     * write for non-wrapped sockets. Note that
-     * OpenSSLSocketImplWrapper overrides setSoTimeout and
-     * getSoTimeout to delegate to the wrapped socket.
-     */
-    private int readTimeoutMilliseconds = 0;
-    private int writeTimeoutMilliseconds = 0;
-
-    private int handshakeTimeoutMilliseconds = -1;  // -1 = same as timeout; 0 = infinite
-
-    OpenSSLSocketImpl(SSLParametersImpl sslParameters) throws IOException {
-        this.socket = this;
-        this.peerHostname = null;
-        this.peerPort = -1;
-        this.autoClose = false;
-        this.sslParameters = sslParameters;
+public abstract class OpenSSLSocketImpl extends AbstractConscryptSocket {
+    OpenSSLSocketImpl() throws IOException {
     }
 
-    OpenSSLSocketImpl(String hostname, int port, SSLParametersImpl sslParameters)
-            throws IOException {
+    OpenSSLSocketImpl(String hostname, int port) throws IOException {
         super(hostname, port);
-        this.socket = this;
-        this.peerHostname = hostname;
-        this.peerPort = port;
-        this.autoClose = false;
-        this.sslParameters = sslParameters;
     }
 
-    OpenSSLSocketImpl(InetAddress address, int port, SSLParametersImpl sslParameters)
-            throws IOException {
+    OpenSSLSocketImpl(InetAddress address, int port) throws IOException {
         super(address, port);
-        this.socket = this;
-        this.peerHostname = null;
-        this.peerPort = -1;
-        this.autoClose = false;
-        this.sslParameters = sslParameters;
     }
 
-
-    OpenSSLSocketImpl(String hostname, int port,
-                                InetAddress clientAddress, int clientPort,
-                                SSLParametersImpl sslParameters) throws IOException {
+    OpenSSLSocketImpl(String hostname, int port, InetAddress clientAddress, int clientPort)
+        throws IOException {
         super(hostname, port, clientAddress, clientPort);
-        this.socket = this;
-        this.peerHostname = hostname;
-        this.peerPort = port;
-        this.autoClose = false;
-        this.sslParameters = sslParameters;
     }
 
-    OpenSSLSocketImpl(InetAddress address, int port,
-                                InetAddress clientAddress, int clientPort,
-                                SSLParametersImpl sslParameters) throws IOException {
+    OpenSSLSocketImpl(InetAddress address, int port, InetAddress clientAddress,
+        int clientPort)
+        throws IOException {
         super(address, port, clientAddress, clientPort);
-        this.socket = this;
-        this.peerHostname = null;
-        this.peerPort = -1;
-        this.autoClose = false;
-        this.sslParameters = sslParameters;
     }
 
-    /**
-     * Create an SSL socket that wraps another socket. Invoked by
-     * OpenSSLSocketImplWrapper constructor.
-     */
-    OpenSSLSocketImpl(Socket socket, String hostname, int port,
-            boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
-        this.socket = socket;
-        this.peerHostname = hostname;
-        this.peerPort = port;
-        this.autoClose = autoClose;
-        this.sslParameters = sslParameters;
-
-        // this.timeout is not set intentionally.
-        // OpenSSLSocketImplWrapper.getSoTimeout will delegate timeout
-        // to wrapped socket
+    OpenSSLSocketImpl(Socket socket, String hostname, int port, boolean autoClose)
+        throws IOException {
+        super(socket, hostname, port, autoClose);
     }
 
     @Override
-    public void connect(SocketAddress endpoint) throws IOException {
-        connect(endpoint, 0);
-    }
-
-    /**
-     * Try to extract the peer's hostname if it's available from the endpoint address.
-     */
-    @Override
-    public void connect(SocketAddress endpoint, int timeout) throws IOException {
-        if (peerHostname == null && endpoint instanceof InetSocketAddress) {
-            peerHostname = Platform.getHostStringFromInetSocketAddress(
-                    (InetSocketAddress) endpoint);
-        }
-
-        super.connect(endpoint, timeout);
-    }
-
-    private void checkOpen() throws SocketException {
-        if (isClosed()) {
-            throw new SocketException("Socket is closed");
-        }
-    }
-
-    /**
-     * Starts a TLS/SSL handshake on this connection using some native methods
-     * from the OpenSSL library. It can negotiate new encryption keys, change
-     * cipher suites, or initiate a new session. The certificate chain is
-     * verified if the correspondent property in java.Security is set. All
-     * listeners are notified at the end of the TLS/SSL handshake.
-     */
-    @Override
-    public void startHandshake() throws IOException {
-        checkOpen();
-        synchronized (stateLock) {
-            if (state == STATE_NEW) {
-                state = STATE_HANDSHAKE_STARTED;
-            } else {
-                // We've either started the handshake already or have been closed.
-                // Do nothing in both cases.
-                return;
-            }
-        }
-
-        final boolean client = sslParameters.getUseClientMode();
-
-        sslNativePointer = 0;
-        boolean releaseResources = true;
-        try {
-            final AbstractSessionContext sessionContext = sslParameters.getSessionContext();
-            sslNativePointer = NativeCrypto.SSL_new(sessionContext.sslCtxNativePointer);
-            Platform.closeGuardOpen(guard, "close");
-
-            boolean enableSessionCreation = getEnableSessionCreation();
-            if (!enableSessionCreation) {
-                NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer,
-                        enableSessionCreation);
-            }
-
-            // Allow servers to trigger renegotiation. Some inadvisable server
-            // configurations cause them to attempt to renegotiate during
-            // certain protocols.
-            NativeCrypto.SSL_accept_renegotiations(sslNativePointer);
-
-            if (client) {
-                NativeCrypto.SSL_set_connect_state(sslNativePointer);
-
-                // Configure OCSP and CT extensions for client
-                NativeCrypto.SSL_enable_ocsp_stapling(sslNativePointer);
-                if (sslParameters.isCTVerificationEnabled(getHostname())) {
-                    NativeCrypto.SSL_enable_signed_cert_timestamps(sslNativePointer);
-                }
-            } else {
-                NativeCrypto.SSL_set_accept_state(sslNativePointer);
-
-                // Configure OCSP for server
-                if (sslParameters.getOCSPResponse() != null) {
-                    NativeCrypto.SSL_enable_ocsp_stapling(sslNativePointer);
-                }
-            }
-
-            final AbstractOpenSSLSession sessionToReuse =
-                    sslParameters.getSessionToReuse(sslNativePointer, getHostnameOrIP(), getPort());
-            sslParameters.setSSLParameters(sslNativePointer, this, this, getHostname());
-            sslParameters.setCertificateValidation(sslNativePointer);
-            sslParameters.setTlsChannelId(sslNativePointer, channelIdPrivateKey);
-
-            // Temporarily use a different timeout for the handshake process
-            int savedReadTimeoutMilliseconds = getSoTimeout();
-            int savedWriteTimeoutMilliseconds = getSoWriteTimeout();
-            if (handshakeTimeoutMilliseconds >= 0) {
-                setSoTimeout(handshakeTimeoutMilliseconds);
-                setSoWriteTimeout(handshakeTimeoutMilliseconds);
-            }
-
-            synchronized (stateLock) {
-                if (state == STATE_CLOSED) {
-                    return;
-                }
-            }
-
-            long sslSessionNativePointer;
-            try {
-                NativeCrypto.SSL_do_handshake(
-                        sslNativePointer, Platform.getFileDescriptor(socket), this, getSoTimeout());
-                sslSessionNativePointer = NativeCrypto.SSL_get1_session(sslNativePointer);
-            } catch (CertificateException e) {
-                SSLHandshakeException wrapper = new SSLHandshakeException(e.getMessage());
-                wrapper.initCause(e);
-                throw wrapper;
-            } catch (SSLException e) {
-                // Swallow this exception if it's thrown as the result of an interruption.
-                //
-                // TODO: SSL_read and SSL_write return -1 when interrupted, but SSL_do_handshake
-                // will throw the last sslError that it saw before sslSelect, usually SSL_WANT_READ
-                // (or WANT_WRITE). Catching that exception here doesn't seem much worse than
-                // changing the native code to return a "special" native pointer value when that
-                // happens.
-                synchronized (stateLock) {
-                    if (state == STATE_CLOSED) {
-                        return;
-                    }
-                }
-
-                // Write CCS errors to EventLog
-                String message = e.getMessage();
-                // Must match error string of SSL_R_UNEXPECTED_CCS
-                if (message.contains("unexpected CCS")) {
-                    String logMessage = String.format("ssl_unexpected_ccs: host=%s",
-                            getHostnameOrIP());
-                    Platform.logEvent(logMessage);
-                }
-
-                throw e;
-            }
-
-            boolean handshakeCompleted = false;
-            synchronized (stateLock) {
-                if (state == STATE_HANDSHAKE_COMPLETED) {
-                    handshakeCompleted = true;
-                } else if (state == STATE_CLOSED) {
-                    return;
-                }
-            }
-
-            sslSession = sslParameters.setupSession(sslSessionNativePointer, sslNativePointer,
-                    sessionToReuse, getHostnameOrIP(), getPort(), handshakeCompleted);
-
-            // Restore the original timeout now that the handshake is complete
-            if (handshakeTimeoutMilliseconds >= 0) {
-                setSoTimeout(savedReadTimeoutMilliseconds);
-                setSoWriteTimeout(savedWriteTimeoutMilliseconds);
-            }
-
-            // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
-            if (handshakeCompleted) {
-                notifyHandshakeCompletedListeners();
-            }
-
-            synchronized (stateLock) {
-                releaseResources = (state == STATE_CLOSED);
-
-                if (state == STATE_HANDSHAKE_STARTED) {
-                    state = STATE_READY_HANDSHAKE_CUT_THROUGH;
-                } else if (state == STATE_HANDSHAKE_COMPLETED) {
-                    state = STATE_READY;
-                }
-
-                if (!releaseResources) {
-                    // Unblock threads that are waiting for our state to transition
-                    // into STATE_READY or STATE_READY_HANDSHAKE_CUT_THROUGH.
-                    stateLock.notifyAll();
-                }
-            }
-        } catch (SSLProtocolException e) {
-            throw (SSLHandshakeException) new SSLHandshakeException("Handshake failed")
-                    .initCause(e);
-        } finally {
-            // on exceptional exit, treat the socket as closed
-            if (releaseResources) {
-                synchronized (stateLock) {
-                    // Mark the socket as closed since we might have reached this as
-                    // a result on an exception thrown by the handshake process.
-                    //
-                    // The state will already be set to closed if we reach this as a result of
-                    // an early return or an interruption due to a concurrent call to close().
-                    state = STATE_CLOSED;
-                    stateLock.notifyAll();
-                }
-
-                try {
-                    shutdownAndFreeSslNative();
-                } catch (IOException ignored) {
-                    // Ignored.
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the hostname that was supplied during socket creation. No DNS resolution is
-     * attempted before returning the hostname.
-     */
     public String getHostname() {
-        return peerHostname;
-    }
-
-    /**
-     * For the purposes of an SSLSession, we want a way to represent the supplied hostname
-     * or the IP address in a textual representation. We do not want to perform reverse DNS
-     * lookups on this address.
-     */
-    public String getHostnameOrIP() {
-        if (peerHostname != null) {
-            return peerHostname;
-        }
-
-        InetAddress peerAddress = getInetAddress();
-        if (peerAddress != null) {
-            return peerAddress.getHostAddress();
-        }
-
-        return null;
+        return super.getHostname();
     }
 
     @Override
-    public int getPort() {
-        return peerPort == -1 ? super.getPort() : peerPort;
-    }
-
-    @Override
-    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / client_cert_cb
-    public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals)
-            throws CertificateEncodingException, SSLException {
-        sslParameters.chooseClientCertificate(keyTypeBytes, asn1DerEncodedPrincipals,
-                sslNativePointer, this);
-    }
-
-    @Override
-    @SuppressWarnings("unused") // used by native psk_client_callback
-    public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) {
-        return sslParameters.clientPSKKeyRequested(identityHint, identity, key, this);
-    }
-
-    @Override
-    @SuppressWarnings("unused") // used by native psk_server_callback
-    public int serverPSKKeyRequested(String identityHint, String identity, byte[] key) {
-        return sslParameters.serverPSKKeyRequested(identityHint, identity, key, this);
-    }
-
-    @Override
-    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / info_callback
-    public void onSSLStateChange(int type, int val) {
-        if (type != NativeConstants.SSL_CB_HANDSHAKE_DONE) {
-            return;
-        }
-
-        synchronized (stateLock) {
-            if (state == STATE_HANDSHAKE_STARTED) {
-                // If sslSession is null, the handshake was completed during
-                // the call to NativeCrypto.SSL_do_handshake and not during a
-                // later read operation. That means we do not need to fix up
-                // the SSLSession and session cache or notify
-                // HandshakeCompletedListeners, it will be done in
-                // startHandshake.
-
-                state = STATE_HANDSHAKE_COMPLETED;
-                return;
-            } else if (state == STATE_READY_HANDSHAKE_CUT_THROUGH) {
-                // We've returned from startHandshake, which means we've set a sslSession etc.
-                // we need to fix them up, which we'll do outside this lock.
-            } else if (state == STATE_CLOSED) {
-                // Someone called "close" but the handshake hasn't been interrupted yet.
-                return;
-            }
-        }
-
-        // reset session id from the native pointer and update the
-        // appropriate cache.
-        sslSession.resetId();
-        AbstractSessionContext sessionContext =
-            (sslParameters.getUseClientMode())
-            ? sslParameters.getClientSessionContext()
-                : sslParameters.getServerSessionContext();
-        sessionContext.putSession(sslSession);
-
-        // let listeners know we are finally done
-        notifyHandshakeCompletedListeners();
-
-        synchronized (stateLock) {
-            // Now that we've fixed up our state, we can tell waiting threads that
-            // we're ready.
-            state = STATE_READY;
-            // Notify all threads waiting for the handshake to complete.
-            stateLock.notifyAll();
-        }
-    }
-
-    void notifyHandshakeCompletedListeners() {
-        if (listeners != null && !listeners.isEmpty()) {
-            // notify the listeners
-            HandshakeCompletedEvent event =
-                new HandshakeCompletedEvent(this, sslSession);
-            for (HandshakeCompletedListener listener : listeners) {
-                try {
-                    listener.handshakeCompleted(event);
-                } catch (RuntimeException e) {
-                    // The RI runs the handlers in a separate thread,
-                    // which we do not. But we try to preserve their
-                    // behavior of logging a problem and not killing
-                    // the handshaking thread just because a listener
-                    // has a problem.
-                    Thread thread = Thread.currentThread();
-                    thread.getUncaughtExceptionHandler().uncaughtException(thread, e);
-                }
-            }
-        }
-    }
-
-    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks
-    @Override
-    public void verifyCertificateChain(long[] certRefs, String authMethod)
-            throws CertificateException {
-        try {
-            X509TrustManager x509tm = sslParameters.getX509TrustManager();
-            if (x509tm == null) {
-                throw new CertificateException("No X.509 TrustManager");
-            }
-            if (certRefs == null || certRefs.length == 0) {
-                throw new SSLException("Peer sent no certificate");
-            }
-            OpenSSLX509Certificate[] peerCertChain =
-                    OpenSSLX509Certificate.createCertChain(certRefs);
-
-            byte[] ocspData = NativeCrypto.SSL_get_ocsp_response(sslNativePointer);
-            byte[] tlsSctData = NativeCrypto.SSL_get_signed_cert_timestamp_list(sslNativePointer);
-
-            // Used for verifyCertificateChain callback
-            handshakeSession = new OpenSSLSessionImpl(
-                    NativeCrypto.SSL_get1_session(sslNativePointer), null, peerCertChain, ocspData,
-                    tlsSctData, getHostnameOrIP(), getPort(), null);
-
-            boolean client = sslParameters.getUseClientMode();
-            if (client) {
-                Platform.checkServerTrusted(x509tm, peerCertChain, authMethod, this);
-            } else {
-                String authType = peerCertChain[0].getPublicKey().getAlgorithm();
-                Platform.checkClientTrusted(x509tm, peerCertChain, authType, this);
-            }
-        } catch (CertificateException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new CertificateException(e);
-        } finally {
-            // Clear this before notifying handshake completed listeners
-            handshakeSession = null;
-        }
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        checkOpen();
-
-        InputStream returnVal;
-        synchronized (stateLock) {
-            if (state == STATE_CLOSED) {
-                throw new SocketException("Socket is closed.");
-            }
-
-            if (is == null) {
-                is = new SSLInputStream();
-            }
-
-            returnVal = is;
-        }
-
-        // Block waiting for a handshake without a lock held. It's possible that the socket
-        // is closed at this point. If that happens, we'll still return the input stream but
-        // all reads on it will throw.
-        waitForHandshake();
-        return returnVal;
-    }
-
-    @Override
-    public OutputStream getOutputStream() throws IOException {
-        checkOpen();
-
-        OutputStream returnVal;
-        synchronized (stateLock) {
-            if (state == STATE_CLOSED) {
-                throw new SocketException("Socket is closed.");
-            }
-
-            if (os == null) {
-                os = new SSLOutputStream();
-            }
-
-            returnVal = os;
-        }
-
-        // Block waiting for a handshake without a lock held. It's possible that the socket
-        // is closed at this point. If that happens, we'll still return the output stream but
-        // all writes on it will throw.
-        waitForHandshake();
-        return returnVal;
-    }
-
-    private void assertReadableOrWriteableState() {
-        if (state == STATE_READY || state == STATE_READY_HANDSHAKE_CUT_THROUGH) {
-            return;
-        }
-
-        throw new AssertionError("Invalid state: " + state);
-    }
-
-
-    private void waitForHandshake() throws IOException {
-        startHandshake();
-
-        synchronized (stateLock) {
-            while (state != STATE_READY &&
-                    state != STATE_READY_HANDSHAKE_CUT_THROUGH &&
-                    state != STATE_CLOSED) {
-                try {
-                    stateLock.wait();
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    throw new IOException("Interrupted waiting for handshake", e);
-                }
-            }
-
-            if (state == STATE_CLOSED) {
-                throw new SocketException("Socket is closed");
-            }
-        }
-    }
-
-    /**
-     * This inner class provides input data stream functionality
-     * for the OpenSSL native implementation. It is used to
-     * read data received via SSL protocol.
-     */
-    private class SSLInputStream extends InputStream {
-        /**
-         * OpenSSL only lets one thread read at a time, so this is used to
-         * make sure we serialize callers of SSL_read. Thread is already
-         * expected to have completed handshaking.
-         */
-        private final Object readLock = new Object();
-
-        SSLInputStream() {
-        }
-
-        /**
-         * Reads one byte. If there is no data in the underlying buffer,
-         * this operation can block until the data will be
-         * available.
-         */
-        @Override
-        public int read() throws IOException {
-            byte[] buffer = new byte[1];
-            int result = read(buffer, 0, 1);
-            return (result != -1) ? buffer[0] & 0xff : -1;
-        }
-
-        /**
-         * Method acts as described in spec for superclass.
-         * @see java.io.InputStream#read(byte[],int,int)
-         */
-        @Override
-        public int read(byte[] buf, int offset, int byteCount) throws IOException {
-            Platform.blockGuardOnNetwork();
-
-            checkOpen();
-            ArrayUtils.checkOffsetAndCount(buf.length, offset, byteCount);
-            if (byteCount == 0) {
-                return 0;
-            }
-
-            synchronized (readLock) {
-                synchronized (stateLock) {
-                    if (state == STATE_CLOSED) {
-                        throw new SocketException("socket is closed");
-                    }
-
-                    if (DBG_STATE) assertReadableOrWriteableState();
-                }
-
-                return NativeCrypto.SSL_read(sslNativePointer, Platform.getFileDescriptor(socket),
-                        OpenSSLSocketImpl.this, buf, offset, byteCount, getSoTimeout());
-            }
-        }
-
-        void awaitPendingOps() {
-            if (DBG_STATE) {
-                synchronized (stateLock) {
-                    if (state != STATE_CLOSED) throw new AssertionError("State is: " + state);
-                }
-            }
-
-            synchronized (readLock) { }
-        }
-    }
-
-    /**
-     * This inner class provides output data stream functionality
-     * for the OpenSSL native implementation. It is used to
-     * write data according to the encryption parameters given in SSL context.
-     */
-    private class SSLOutputStream extends OutputStream {
-
-        /**
-         * OpenSSL only lets one thread write at a time, so this is used
-         * to make sure we serialize callers of SSL_write. Thread is
-         * already expected to have completed handshaking.
-         */
-        private final Object writeLock = new Object();
-
-        SSLOutputStream() {
-        }
-
-        /**
-         * Method acts as described in spec for superclass.
-         * @see java.io.OutputStream#write(int)
-         */
-        @Override
-        public void write(int oneByte) throws IOException {
-            byte[] buffer = new byte[1];
-            buffer[0] = (byte) (oneByte & 0xff);
-            write(buffer);
-        }
-
-        /**
-         * Method acts as described in spec for superclass.
-         * @see java.io.OutputStream#write(byte[],int,int)
-         */
-        @Override
-        public void write(byte[] buf, int offset, int byteCount) throws IOException {
-            Platform.blockGuardOnNetwork();
-            checkOpen();
-            ArrayUtils.checkOffsetAndCount(buf.length, offset, byteCount);
-            if (byteCount == 0) {
-                return;
-            }
-
-            synchronized (writeLock) {
-                synchronized (stateLock) {
-                    if (state == STATE_CLOSED) {
-                        throw new SocketException("socket is closed");
-                    }
-
-                    if (DBG_STATE) assertReadableOrWriteableState();
-                }
-
-                NativeCrypto.SSL_write(sslNativePointer, Platform.getFileDescriptor(socket),
-                        OpenSSLSocketImpl.this, buf, offset, byteCount, writeTimeoutMilliseconds);
-            }
-        }
-
-
-        void awaitPendingOps() {
-            if (DBG_STATE) {
-                synchronized (stateLock) {
-                    if (state != STATE_CLOSED) throw new AssertionError("State is: " + state);
-                }
-            }
-
-            synchronized (writeLock) { }
-        }
-    }
-
-
-    @Override
-    public SSLSession getSession() {
-        if (sslSession == null) {
-            boolean handshakeCompleted = false;
-            try {
-                if (isConnected()) {
-                    waitForHandshake();
-                    handshakeCompleted = true;
-                }
-            } catch (IOException e) {
-                // Fall through.
-            }
-
-            if (!handshakeCompleted) {
-                // return an invalid session with
-                // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
-                return SSLNullSession.getNullSession();
-            }
-        }
-        return Platform.wrapSSLSession(sslSession);
-    }
-
-    /* @Override */
-    @SuppressWarnings("MissingOverride")  // For compilation with Java 6.
-    public SSLSession getHandshakeSession() {
-        return handshakeSession;
-    }
-
-    @Override
-    public void addHandshakeCompletedListener(
-            HandshakeCompletedListener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("Provided listener is null");
-        }
-        if (listeners == null) {
-            listeners = new ArrayList<HandshakeCompletedListener>();
-        }
-        listeners.add(listener);
-    }
-
-    @Override
-    public void removeHandshakeCompletedListener(
-            HandshakeCompletedListener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("Provided listener is null");
-        }
-        if (listeners == null) {
-            throw new IllegalArgumentException(
-                    "Provided listener is not registered");
-        }
-        if (!listeners.remove(listener)) {
-            throw new IllegalArgumentException(
-                    "Provided listener is not registered");
-        }
-    }
-
-    @Override
-    public boolean getEnableSessionCreation() {
-        return sslParameters.getEnableSessionCreation();
-    }
-
-    @Override
-    public void setEnableSessionCreation(boolean flag) {
-        sslParameters.setEnableSessionCreation(flag);
-    }
-
-    @Override
-    public String[] getSupportedCipherSuites() {
-        return NativeCrypto.getSupportedCipherSuites();
-    }
-
-    @Override
-    public String[] getEnabledCipherSuites() {
-        return sslParameters.getEnabledCipherSuites();
-    }
-
-    @Override
-    public void setEnabledCipherSuites(String[] suites) {
-        sslParameters.setEnabledCipherSuites(suites);
-    }
-
-    @Override
-    public String[] getSupportedProtocols() {
-        return NativeCrypto.getSupportedProtocols();
-    }
-
-    @Override
-    public String[] getEnabledProtocols() {
-        return sslParameters.getEnabledProtocols();
-    }
-
-    @Override
-    public void setEnabledProtocols(String[] protocols) {
-        sslParameters.setEnabledProtocols(protocols);
-    }
-
-    /**
-     * This method enables session ticket support.
-     *
-     * @param useSessionTickets True to enable session tickets
-     */
-    public void setUseSessionTickets(boolean useSessionTickets) {
-        sslParameters.setUseSessionTickets(useSessionTickets);
-    }
-
-    /**
-     * This method enables Server Name Indication
-     *
-     * @param hostname the desired SNI hostname, or null to disable
-     */
     public void setHostname(String hostname) {
-        sslParameters.setUseSni(hostname != null);
-        peerHostname = hostname;
-    }
-
-    /**
-     * Enables/disables TLS Channel ID for this server socket.
-     *
-     * <p>This method needs to be invoked before the handshake starts.
-     *
-     * @throws IllegalStateException if this is a client socket or if the handshake has already
-     *         started.
-     */
-    public void setChannelIdEnabled(boolean enabled) {
-        if (getUseClientMode()) {
-            throw new IllegalStateException("Client mode");
-        }
-
-        synchronized (stateLock) {
-            if (state != STATE_NEW) {
-                throw new IllegalStateException(
-                        "Could not enable/disable Channel ID after the initial handshake has"
-                                + " begun.");
-            }
-        }
-        sslParameters.channelIdEnabled = enabled;
-    }
-
-    /**
-     * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
-     * handshake completes.
-     *
-     * @return channel ID or {@code null} if not available.
-     *
-     * @throws IllegalStateException if this is a client socket or if the handshake has not yet
-     *         completed.
-     * @throws SSLException if channel ID is available but could not be obtained.
-     */
-    public byte[] getChannelId() throws SSLException {
-        if (getUseClientMode()) {
-            throw new IllegalStateException("Client mode");
-        }
-
-        synchronized (stateLock) {
-            if (state != STATE_READY) {
-                throw new IllegalStateException(
-                        "Channel ID is only available after handshake completes");
-            }
-        }
-        return NativeCrypto.SSL_get_tls_channel_id(sslNativePointer);
-    }
-
-    /**
-     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
-     *
-     * <p>This method needs to be invoked before the handshake starts.
-     *
-     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
-     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
-     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
-     *
-     * @throws IllegalStateException if this is a server socket or if the handshake has already
-     *         started.
-     */
-    public void setChannelIdPrivateKey(PrivateKey privateKey) {
-        if (!getUseClientMode()) {
-            throw new IllegalStateException("Server mode");
-        }
-
-        synchronized (stateLock) {
-            if (state != STATE_NEW) {
-                throw new IllegalStateException(
-                        "Could not change Channel ID private key after the initial handshake has"
-                                + " begun.");
-            }
-        }
-
-        if (privateKey == null) {
-            sslParameters.channelIdEnabled = false;
-            channelIdPrivateKey = null;
-        } else {
-            sslParameters.channelIdEnabled = true;
-            try {
-                ECParameterSpec ecParams = null;
-                if (privateKey instanceof ECKey) {
-                    ecParams = ((ECKey) privateKey).getParams();
-                }
-                if (ecParams == null) {
-                    // Assume this is a P-256 key, as specified in the contract of this method.
-                    ecParams =
-                            OpenSSLECGroupContext.getCurveByName("prime256v1").getECParameterSpec();
-                }
-                channelIdPrivateKey =
-                        OpenSSLKey.fromECPrivateKeyForTLSStackOnly(privateKey, ecParams);
-            } catch (InvalidKeyException e) {
-                // Will have error in startHandshake
-            }
-        }
+        super.setHostname(hostname);
     }
 
     @Override
-    public boolean getUseClientMode() {
-        return sslParameters.getUseClientMode();
+    public String getHostnameOrIP() {
+        return super.getHostnameOrIP();
     }
 
     @Override
-    public void setUseClientMode(boolean mode) {
-        synchronized (stateLock) {
-            if (state != STATE_NEW) {
-                throw new IllegalArgumentException(
-                        "Could not change the mode after the initial handshake has begun.");
-            }
-        }
-        sslParameters.setUseClientMode(mode);
-    }
-
-    @Override
-    public boolean getWantClientAuth() {
-        return sslParameters.getWantClientAuth();
-    }
-
-    @Override
-    public boolean getNeedClientAuth() {
-        return sslParameters.getNeedClientAuth();
-    }
-
-    @Override
-    public void setNeedClientAuth(boolean need) {
-        sslParameters.setNeedClientAuth(need);
-    }
-
-    @Override
-    public void setWantClientAuth(boolean want) {
-        sslParameters.setWantClientAuth(want);
-    }
-
-    @Override
-    public void sendUrgentData(int data) throws IOException {
-        throw new SocketException("Method sendUrgentData() is not supported.");
-    }
-
-    @Override
-    public void setOOBInline(boolean on) throws SocketException {
-        throw new SocketException("Methods sendUrgentData, setOOBInline are not supported.");
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public void setSoTimeout(int readTimeoutMilliseconds) throws SocketException {
-        if (socket != this) {
-            socket.setSoTimeout(readTimeoutMilliseconds);
-        } else {
-            super.setSoTimeout(readTimeoutMilliseconds);
-        }
-
-        this.readTimeoutMilliseconds = readTimeoutMilliseconds;
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public int getSoTimeout() throws SocketException {
-        return readTimeoutMilliseconds;
-    }
-
-    /**
-     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
-     */
-    public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
-        this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
-
-        Platform.setSocketWriteTimeout(this, writeTimeoutMilliseconds);
-    }
-
-    /**
-     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
-     */
-    public int getSoWriteTimeout() throws SocketException {
-        return writeTimeoutMilliseconds;
-    }
-
-    /**
-     * Set the handshake timeout on this socket.  This timeout is specified in
-     * milliseconds and will be used only during the handshake process.
-     */
-    public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
-        this.handshakeTimeoutMilliseconds = handshakeTimeoutMilliseconds;
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public void close() throws IOException {
-        // TODO: Close SSL sockets using a background thread so they close gracefully.
-
-        SSLInputStream sslInputStream;
-        SSLOutputStream sslOutputStream;
-
-        synchronized (stateLock) {
-            if (state == STATE_CLOSED) {
-                // close() has already been called, so do nothing and return.
-                return;
-            }
-
-            int oldState = state;
-            state = STATE_CLOSED;
-
-            if (oldState == STATE_NEW) {
-                // The handshake hasn't been started yet, so there's no OpenSSL related
-                // state to clean up. We still need to close the underlying socket if
-                // we're wrapping it and were asked to autoClose.
-                closeUnderlyingSocket();
-
-                stateLock.notifyAll();
-                return;
-            }
-
-            if (oldState != STATE_READY && oldState != STATE_READY_HANDSHAKE_CUT_THROUGH) {
-                // If we're in these states, we still haven't returned from startHandshake.
-                // We call SSL_interrupt so that we can interrupt SSL_do_handshake and then
-                // set the state to STATE_CLOSED. startHandshake will handle all cleanup
-                // after SSL_do_handshake returns, so we don't have anything to do here.
-                NativeCrypto.SSL_interrupt(sslNativePointer);
-
-                stateLock.notifyAll();
-                return;
-            }
-
-            stateLock.notifyAll();
-            // We've already returned from startHandshake, so we potentially have
-            // input and output streams to clean up.
-            sslInputStream = is;
-            sslOutputStream = os;
-        }
-
-        // Don't bother interrupting unless we have something to interrupt.
-        if (sslInputStream != null || sslOutputStream != null) {
-            NativeCrypto.SSL_interrupt(sslNativePointer);
-        }
-
-        // Wait for the input and output streams to finish any reads they have in
-        // progress. If there are no reads in progress at this point, future reads will
-        // throw because state == STATE_CLOSED
-        if (sslInputStream != null) {
-            sslInputStream.awaitPendingOps();
-        }
-        if (sslOutputStream != null) {
-            sslOutputStream.awaitPendingOps();
-        }
-
-        shutdownAndFreeSslNative();
-    }
-
-    private void shutdownAndFreeSslNative() throws IOException {
-        try {
-            Platform.blockGuardOnNetwork();
-            NativeCrypto.SSL_shutdown(sslNativePointer, Platform.getFileDescriptor(socket),
-                    this);
-        } catch (IOException ignored) {
-            /*
-            * Note that although close() can throw
-            * IOException, the RI does not throw if there
-            * is problem sending a "close notify" which
-            * can happen if the underlying socket is closed.
-            */
-        } finally {
-            free();
-            closeUnderlyingSocket();
-        }
-    }
-
-    private void closeUnderlyingSocket() throws IOException {
-        if (socket != this) {
-            if (autoClose && !socket.isClosed()) {
-                socket.close();
-            }
-        } else {
-            if (!super.isClosed()) {
-                super.close();
-            }
-        }
-    }
-
-    private void free() {
-        if (sslNativePointer == 0) {
-            return;
-        }
-        NativeCrypto.SSL_free(sslNativePointer);
-        sslNativePointer = 0;
-        Platform.closeGuardClose(guard);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            /*
-             * Just worry about our own state. Notably we do not try and
-             * close anything. The SocketImpl, either our own
-             * PlainSocketImpl, or the Socket we are wrapping, will do
-             * that. This might mean we do not properly SSL_shutdown, but
-             * if you want to do that, properly close the socket yourself.
-             *
-             * The reason why we don't try to SSL_shutdown, is that there
-             * can be a race between finalizers where the PlainSocketImpl
-             * finalizer runs first and closes the socket. However, in the
-             * meanwhile, the underlying file descriptor could be reused
-             * for another purpose. If we call SSL_shutdown, the
-             * underlying socket BIOs still have the old file descriptor
-             * and will write the close notify to some unsuspecting
-             * reader.
-             */
-            if (guard != null) {
-                Platform.closeGuardWarnIfOpen(guard);
-            }
-            free();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /* @Override */
     public FileDescriptor getFileDescriptor$() {
-        if (socket == this) {
-            return Platform.getFileDescriptorFromSSLSocket(this);
-        } else {
-            return Platform.getFileDescriptor(socket);
-        }
-    }
-
-    /**
-     * Returns null always for backward compatibility.
-     */
-    public byte[] getNpnSelectedProtocol() {
-        return null;
-    }
-
-    /**
-     * Returns the protocol agreed upon by client and server, or {@code null} if
-     * no protocol was agreed upon.
-     */
-    public byte[] getAlpnSelectedProtocol() {
-        return NativeCrypto.SSL_get0_alpn_selected(sslNativePointer);
-    }
-
-    /**
-     * This method does nothing and is kept for backward compatibility.
-     */
-    public void setNpnProtocols(byte[] npnProtocols) {
-    }
-
-    /**
-     * Sets the list of ALPN protocols. This method internally converts the protocols to their
-     * wire-format form.
-     *
-     * @param alpnProtocols the list of ALPN protocols
-     * @see #setAlpnProtocols(byte[])
-     */
-    public void setAlpnProtocols(String[] alpnProtocols) {
-        sslParameters.setAlpnProtocols(alpnProtocols);
-    }
-
-    /**
-     * Alternate version of {@link #setAlpnProtocols(String[])} that directly sets the list of
-     * ALPN in the wire-format form used by BoringSSL (length-prefixed 8-bit strings).
-     * Requires that all strings be encoded with US-ASCII.
-     *
-     * @param alpnProtocols the encoded form of the ALPN protocol list
-     * @see #setAlpnProtocols(String[])
-     */
-    public void setAlpnProtocols(byte[] alpnProtocols) {
-        sslParameters.setAlpnProtocols(alpnProtocols);
+        return super.getFileDescriptor$();
     }
 
     @Override
-    public SSLParameters getSSLParameters() {
-        SSLParameters params = super.getSSLParameters();
-        Platform.getSSLParameters(params, sslParameters, this);
-        return params;
+    public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+        super.setSoWriteTimeout(writeTimeoutMilliseconds);
     }
 
     @Override
-    public void setSSLParameters(SSLParameters p) {
-        super.setSSLParameters(p);
-        Platform.setSSLParameters(p, sslParameters, this);
+    public int getSoWriteTimeout() throws SocketException {
+        return super.getSoWriteTimeout();
     }
 
     @Override
-    public String chooseServerAlias(X509KeyManager keyManager, String keyType) {
-        return keyManager.chooseServerAlias(keyType, null, this);
+    public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+        super.setHandshakeTimeout(handshakeTimeoutMilliseconds);
     }
 
     @Override
-    public String chooseClientAlias(X509KeyManager keyManager, X500Principal[] issuers,
-            String[] keyTypes) {
-        return keyManager.chooseClientAlias(keyTypes, null, this);
+    public abstract SSLSession getHandshakeSession();
+
+    @Override
+    public abstract void setUseSessionTickets(boolean useSessionTickets);
+
+    @Override
+    public abstract void setChannelIdEnabled(boolean enabled);
+
+    @Override
+    public abstract byte[] getChannelId() throws SSLException;
+
+    @Override
+    public abstract void setChannelIdPrivateKey(PrivateKey privateKey);
+
+    @Override
+    public final byte[] getNpnSelectedProtocol() {
+        return super.getNpnSelectedProtocol();
     }
 
     @Override
-    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
-    public String chooseServerPSKIdentityHint(PSKKeyManager keyManager) {
-        return keyManager.chooseServerKeyIdentityHint(this);
+    public final void setNpnProtocols(byte[] npnProtocols) {
+        super.setNpnProtocols(npnProtocols);
     }
 
     @Override
-    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
-    public String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) {
-        return keyManager.chooseClientKeyIdentity(identityHint, this);
-    }
+    public abstract byte[] getAlpnSelectedProtocol();
 
     @Override
-    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
-    public SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) {
-        return keyManager.getKey(identityHint, identity, this);
-    }
+    public abstract void setAlpnProtocols(String[] alpnProtocols);
+
+    @Override
+    public abstract void setAlpnProtocols(byte[] alpnProtocols);
 }
diff --git a/common/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java b/common/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java
deleted file mode 100644
index 848ef7f..0000000
--- a/common/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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 org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-/**
- * This class wraps the SSL functionality over an existing connected socket.
- */
-class OpenSSLSocketImplWrapper extends OpenSSLSocketImpl {
-
-    private Socket socket;
-
-    OpenSSLSocketImplWrapper(Socket socket, String hostname, int port,
-            boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
-        super(socket, hostname, port, autoClose, sslParameters);
-        if (!socket.isConnected()) {
-            throw new SocketException("Socket is not connected.");
-        }
-        this.socket = socket;
-    }
-
-    @Override
-    public void connect(SocketAddress sockaddr, int timeout)
-        throws IOException {
-        socket.connect(sockaddr, timeout);
-    }
-
-    @Override
-    public void connect(SocketAddress sockaddr) throws IOException {
-        socket.connect(sockaddr);
-    }
-
-    @Override
-    public void bind(SocketAddress sockaddr) throws IOException {
-        socket.bind(sockaddr);
-    }
-
-    @Override
-    public SocketAddress getRemoteSocketAddress() {
-        return socket.getRemoteSocketAddress();
-    }
-
-    @Override
-    public SocketAddress getLocalSocketAddress() {
-        return socket.getLocalSocketAddress();
-    }
-
-    @Override
-    public InetAddress getLocalAddress() {
-        return socket.getLocalAddress();
-    }
-
-    @Override
-    public InetAddress getInetAddress() {
-        return socket.getInetAddress();
-    }
-
-    @Override
-    public String toString() {
-        return "SSL socket over " + socket.toString();
-    }
-
-    @Override
-    public void setSoLinger(boolean on, int linger) throws SocketException {
-        socket.setSoLinger(on, linger);
-    }
-
-    @Override
-    public void setTcpNoDelay(boolean on) throws SocketException {
-        socket.setTcpNoDelay(on);
-    }
-
-    @Override
-    public void setReuseAddress(boolean on) throws SocketException {
-        socket.setReuseAddress(on);
-    }
-
-    @Override
-    public void setKeepAlive(boolean on) throws SocketException {
-        socket.setKeepAlive(on);
-    }
-
-    @Override
-    public void setTrafficClass(int tos) throws SocketException {
-        socket.setTrafficClass(tos);
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public void setSendBufferSize(int size) throws SocketException {
-        socket.setSendBufferSize(size);
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public void setReceiveBufferSize(int size) throws SocketException {
-        socket.setReceiveBufferSize(size);
-    }
-
-    @Override
-    public boolean getTcpNoDelay() throws SocketException {
-        return socket.getTcpNoDelay();
-    }
-
-    @Override
-    public boolean getReuseAddress() throws SocketException {
-        return socket.getReuseAddress();
-    }
-
-    @Override
-    public boolean getOOBInline() throws SocketException {
-        return socket.getOOBInline();
-    }
-
-    @Override
-    public boolean getKeepAlive() throws SocketException {
-        return socket.getKeepAlive();
-    }
-
-    @Override
-    public int getTrafficClass() throws SocketException {
-        return socket.getTrafficClass();
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public int getSoTimeout() throws SocketException {
-        return socket.getSoTimeout();
-    }
-
-    @Override
-    public int getSoLinger() throws SocketException {
-        return socket.getSoLinger();
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public int getSendBufferSize() throws SocketException {
-        return socket.getSendBufferSize();
-    }
-
-    @Override
-    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
-    public int getReceiveBufferSize() throws SocketException {
-        return socket.getReceiveBufferSize();
-    }
-
-    @Override
-    public boolean isConnected() {
-        return socket.isConnected();
-    }
-
-    @Override
-    public boolean isClosed() {
-        return socket.isClosed();
-    }
-
-    @Override
-    public boolean isBound() {
-        return socket.isBound();
-    }
-
-    @Override
-    public boolean isOutputShutdown() {
-        return socket.isOutputShutdown();
-    }
-
-    @Override
-    public boolean isInputShutdown() {
-        return socket.isInputShutdown();
-    }
-
-    @Override
-    public int getPort() {
-        return socket.getPort();
-    }
-
-    @Override
-    public int getLocalPort() {
-        return socket.getLocalPort();
-    }
-}
diff --git a/common/src/main/java/org/conscrypt/PeerInfoProvider.java b/common/src/main/java/org/conscrypt/PeerInfoProvider.java
index dfa3fc7..e70f0cd 100644
--- a/common/src/main/java/org/conscrypt/PeerInfoProvider.java
+++ b/common/src/main/java/org/conscrypt/PeerInfoProvider.java
@@ -21,6 +21,11 @@
 abstract class PeerInfoProvider {
     private static final PeerInfoProvider NULL_PEER_INFO_PROVIDER = new PeerInfoProvider() {
         @Override
+        String getHostname() {
+            return null;
+        }
+
+        @Override
         public String getHostnameOrIP() {
             return null;
         }
@@ -32,6 +37,12 @@
     };
 
     /**
+     * Returns the hostname supplied during engine/socket creation. No DNS resolution is
+     * attempted before returning the hostname.
+     */
+    abstract String getHostname();
+
+    /**
      * This method attempts to create a textual representation of the peer host or IP. Does
      * not perform a reverse DNS lookup. This is typically used during session creation.
      */
@@ -49,6 +60,11 @@
     static PeerInfoProvider forHostAndPort(final String host, final int port) {
         return new PeerInfoProvider() {
             @Override
+            String getHostname() {
+                return host;
+            }
+
+            @Override
             public String getHostnameOrIP() {
                 return host;
             }
diff --git a/common/src/main/java/org/conscrypt/SSLUtils.java b/common/src/main/java/org/conscrypt/SSLUtils.java
index efdf134..74e6cc5 100644
--- a/common/src/main/java/org/conscrypt/SSLUtils.java
+++ b/common/src/main/java/org/conscrypt/SSLUtils.java
@@ -50,8 +50,8 @@
  * This is a public class to allow testing to occur on Android via CTS.
  */
 final class SSLUtils {
-    static final boolean USE_ENGINE_SOCKET_BY_DEFAULT =
-            Boolean.parseBoolean(System.getProperty("org.conscrypt.useEngineSocketByDefault"));
+    static final boolean USE_ENGINE_SOCKET_BY_DEFAULT = Boolean.parseBoolean(
+            System.getProperty("org.conscrypt.useEngineSocketByDefault", "false"));
     private static final int MAX_PROTOCOL_LENGTH = 255;
 
     /**
diff --git a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 7c51c20..776a19dd 100644
--- a/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/openjdk-integ-tests/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -676,27 +676,38 @@
         server.close();
         c.close();
     }
+
     @Test
-    public void test_SSLSocket_setUseClientMode() throws Exception {
-        // client is client, server is server
+    public void testClientMode_normal() throws Exception {
+        // Client is client and server is server.
         test_SSLSocket_setUseClientMode(true, false);
-        // client is server, server is client
-        test_SSLSocket_setUseClientMode(true, false);
-        // both are client
-        try {
-            test_SSLSocket_setUseClientMode(true, true);
-            fail();
-        } catch (SSLProtocolException | SSLHandshakeException expected) {
-            // Ignored.
-        }
-        // both are server
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void testClientMode_reverse() throws Exception {
+        // Client is server and server is client.
+        test_SSLSocket_setUseClientMode(false, true);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void testClientMode_bothClient() throws Exception {
+        test_SSLSocket_setUseClientMode(true, true);
+    }
+
+    @Test
+    public void testClientMode_bothServer() throws Exception {
         try {
             test_SSLSocket_setUseClientMode(false, false);
             fail();
         } catch (SocketTimeoutException expected) {
-            // Ignored.
+            // Ignore
+        } catch (SSLHandshakeException expected) {
+            // Depending on the timing of the socket closures, this can happen as well.
+            assertTrue("Unexpected handshake error: " + expected.getMessage(),
+                    expected.getMessage().toLowerCase().contains("connection closed"));
         }
     }
+
     private void test_SSLSocket_setUseClientMode(
             final boolean clientClientMode, final boolean serverClientMode) throws Exception {
         TestSSLContext c = TestSSLContext.create();
@@ -1595,13 +1606,13 @@
         }
     }
 
-    // TODO(nmittler): FD socket read may return -1 instead of SocketException.
+    // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
     @Test
     public void test_SSLSocket_interrupt_readUnderlyingAndCloseUnderlying() throws Exception {
         test_SSLSocket_interrupt_case(true, true);
     }
 
-    // TODO(nmittler): FD socket read may return -1 instead of SocketException.
+    // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
     @Test
     public void test_SSLSocket_interrupt_readUnderlyingAndCloseWrapper() throws Exception {
         test_SSLSocket_interrupt_case(true, false);
@@ -1613,7 +1624,7 @@
         test_SSLSocket_interrupt_case(false, true);
     }
 
-    // TODO(nmittler): FD socket read may return -1 instead of SocketException.
+    // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
     @Test
     public void test_SSLSocket_interrupt_readWrapperAndCloseWrapper() throws Exception {
         test_SSLSocket_interrupt_case(false, false);
@@ -1660,11 +1671,11 @@
             toRead.setSoTimeout(readingTimeoutMillis);
             final InputStream inputStream = toRead.getInputStream();
             int value = inputStream.read();
-            if (isConscryptFdSocket(clientWrapping)) {
-                // TODO(nmittler): FD socket read may return -1 instead of SocketException.
+            if (isConscryptSocket(clientWrapping)) {
+                // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
                 assertEquals(-1, value);
             } else {
-                // For every other condition, we should expect SocketException.
+                // For any other socket type, we should expect SocketException.
                 fail();
             }
         } catch (SocketException e) {
@@ -1682,29 +1693,33 @@
      * thread will interrupt another thread blocked reading on the same
      * socket.
      */
+    // TODO(nmittler): Interrupts do not work with the engine-based socket.
     @Test
-    public void test_SSLSocket_interrupt_read() throws Exception {
+    public void test_SSLSocket_interrupt_read_withoutAutoClose() throws Exception {
         final int readingTimeoutMillis = 5000;
         TestSSLContext c = TestSSLContext.create();
         final Socket underlying = new Socket(c.host, c.port);
         final SSLSocket wrapping = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
                 underlying, c.host.getHostName(), c.port, false);
+
+        // TODO(nmittler): Interrupts do not work with the engine-based socket.
+        assumeFalse(isConscryptEngineSocket(wrapping));
+
         Future<Void> clientFuture = runAsync(() -> {
             wrapping.startHandshake();
             try {
                 wrapping.setSoTimeout(readingTimeoutMillis);
                 int ret = wrapping.getInputStream().read();
                 // Android returns -1 rather than throwing.
-                if (isConscryptFdSocket(wrapping)) {
-                    // This seems to only happen with Conscrypt's FD-based socket.
+                if (isConscryptSocket(wrapping)) {
+                    // TODO(nmittler): Conscrypt socket read may return -1 instead of
+                    // SocketException.
                     assertEquals(-1, ret);
                 } else {
-                    // For every other condition, we should expect SocketException.
+                    // For any other socket type, we should expect SocketException.
                     fail();
                 }
             } catch (SocketException e) {
-                // Opposite condition of the one above. Verify the behavior we expect.
-                assertFalse(isConscryptFdSocket(wrapping));
                 // Otherwise, ignore the exception since it's expected.
             }
             return null;
@@ -1733,6 +1748,7 @@
         }
 
         wrapping.close();
+
         clientFuture.get();
         server.close();
     }
@@ -2277,8 +2293,16 @@
         }
     }
 
+    private static boolean isConscryptSocket(Socket socket) {
+        return isConscryptFdSocket(socket) || isConscryptEngineSocket(socket);
+    }
+
     private static boolean isConscryptFdSocket(Socket socket) {
-        return "OpenSSLSocketImplWrapper".equals(socket.getClass().getSimpleName());
+        return "ConscryptFileDescriptorSocket".equals(socket.getClass().getSimpleName());
+    }
+
+    private static boolean isConscryptEngineSocket(Socket socket) {
+        return "ConscryptEngineSocket".equals(socket.getClass().getSimpleName());
     }
 
     private static String osName() {
diff --git a/openjdk/src/main/java/org/conscrypt/Platform.java b/openjdk/src/main/java/org/conscrypt/Platform.java
index 0da249c..7b5adb6 100644
--- a/openjdk/src/main/java/org/conscrypt/Platform.java
+++ b/openjdk/src/main/java/org/conscrypt/Platform.java
@@ -87,8 +87,8 @@
         }
     }
 
-    static FileDescriptor getFileDescriptorFromSSLSocket(OpenSSLSocketImpl openSSLSocketImpl) {
-        return getFileDescriptor(openSSLSocketImpl);
+    static FileDescriptor getFileDescriptorFromSSLSocket(AbstractConscryptSocket socket) {
+        return getFileDescriptor(socket);
     }
 
     static String getCurveName(ECParameterSpec spec) {
@@ -117,7 +117,7 @@
 
     @SuppressWarnings("unchecked")
     public static void setSSLParameters(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket) {
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
         impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
         try {
             Method getUseCipherSuitesOrder =
@@ -147,7 +147,7 @@
 
     @SuppressWarnings({"LiteralClassName", "rawtypes"})
     public static void getSSLParameters(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket) {
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
         params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
         try {
             Method setUseCipherSuitesOrder =
@@ -234,7 +234,7 @@
     }
 
     static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
-            OpenSSLSocketImpl socket) throws CertificateException {
+            AbstractConscryptSocket socket) throws CertificateException {
         if (tm instanceof X509ExtendedTrustManager) {
             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
             x509etm.checkClientTrusted(chain, authType, socket);
@@ -244,7 +244,7 @@
     }
 
     static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
-            OpenSSLSocketImpl socket) throws CertificateException {
+            AbstractConscryptSocket socket) throws CertificateException {
         if (tm instanceof X509ExtendedTrustManager) {
             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
             x509etm.checkServerTrusted(chain, authType, socket);
diff --git a/openjdk/src/test/java/org/conscrypt/OpenSSLServerSocketImplTest.java b/openjdk/src/test/java/org/conscrypt/ConscryptServerSocketTest.java
similarity index 98%
rename from openjdk/src/test/java/org/conscrypt/OpenSSLServerSocketImplTest.java
rename to openjdk/src/test/java/org/conscrypt/ConscryptServerSocketTest.java
index d84b72a..419469c 100644
--- a/openjdk/src/test/java/org/conscrypt/OpenSSLServerSocketImplTest.java
+++ b/openjdk/src/test/java/org/conscrypt/ConscryptServerSocketTest.java
@@ -41,7 +41,7 @@
 import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class OpenSSLServerSocketImplTest {
+public class ConscryptServerSocketTest {
     private static final String CIPHER = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
     private static final int MESSAGE_SIZE = 4096;
 
diff --git a/openjdk/src/test/java/org/conscrypt/OpenSSLSocketImplTest.java b/openjdk/src/test/java/org/conscrypt/OpenSSLSocketImplTest.java
index 8c59e8f..249878c 100644
--- a/openjdk/src/test/java/org/conscrypt/OpenSSLSocketImplTest.java
+++ b/openjdk/src/test/java/org/conscrypt/OpenSSLSocketImplTest.java
@@ -77,7 +77,7 @@
             @Override
             void assertSocketType(Socket socket) {
                 assertTrue("Unexpected socket type: " + socket.getClass().getName(),
-                        socket instanceof OpenSSLEngineSocketImpl);
+                        socket instanceof ConscryptEngineSocket);
             }
         };
 
@@ -87,23 +87,23 @@
             this.useEngineSocket = useEngineSocket;
         }
 
-        OpenSSLSocketImpl createClientSocket(OpenSSLContextImpl context, ServerSocket listener)
-                throws IOException {
+        AbstractConscryptSocket createClientSocket(
+                OpenSSLContextImpl context, ServerSocket listener) throws IOException {
             SSLSocketFactory factory = context.engineGetSocketFactory();
             Conscrypt.SocketFactories.setUseEngineSocket(factory, useEngineSocket);
-            OpenSSLSocketImpl socket = (OpenSSLSocketImpl) factory.createSocket(
+            AbstractConscryptSocket socket = (AbstractConscryptSocket) factory.createSocket(
                     listener.getInetAddress(), listener.getLocalPort());
             assertSocketType(socket);
             socket.setUseClientMode(true);
             return socket;
         }
 
-        OpenSSLSocketImpl createServerSocket(OpenSSLContextImpl context, ServerSocket listener)
-                throws IOException {
+        AbstractConscryptSocket createServerSocket(
+                OpenSSLContextImpl context, ServerSocket listener) throws IOException {
             SSLSocketFactory factory = context.engineGetSocketFactory();
             Conscrypt.SocketFactories.setUseEngineSocket(factory, useEngineSocket);
-            OpenSSLSocketImpl socket = (OpenSSLSocketImpl) factory.createSocket(listener.accept(),
-                    null, -1, // hostname, port
+            AbstractConscryptSocket socket = (AbstractConscryptSocket) factory.createSocket(
+                    listener.accept(), null, -1, // hostname, port
                     true); // autoclose
             assertSocketType(socket);
             socket.setUseClientMode(false);
@@ -152,7 +152,7 @@
         KeyManager[] keyManagers;
         TrustManager[] trustManagers;
 
-        abstract OpenSSLSocketImpl createSocket(ServerSocket listener) throws IOException;
+        abstract AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException;
 
         OpenSSLContextImpl createContext() throws IOException {
             OpenSSLContextImpl context = OpenSSLContextImpl.getPreferred();
@@ -192,8 +192,9 @@
         }
 
         @Override
-        OpenSSLSocketImpl createSocket(ServerSocket listener) throws IOException {
-            OpenSSLSocketImpl socket = socketType.createClientSocket(createContext(), listener);
+        AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException {
+            AbstractConscryptSocket socket =
+                    socketType.createClientSocket(createContext(), listener);
             socket.setHostname(hostname);
             return socket;
         }
@@ -217,7 +218,7 @@
         }
 
         @Override
-        OpenSSLSocketImpl createSocket(ServerSocket listener) throws IOException {
+        AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException {
             return socketType.createServerSocket(createContext(), listener);
         }
     }
@@ -226,8 +227,8 @@
         ServerHooks serverHooks;
         ClientHooks clientHooks;
 
-        OpenSSLSocketImpl client;
-        OpenSSLSocketImpl server;
+        AbstractConscryptSocket client;
+        AbstractConscryptSocket server;
 
         Exception clientException;
         Exception serverException;
@@ -274,8 +275,8 @@
 
         void doHandshake() throws Exception {
             ServerSocket listener = newServerSocket();
-            Future<OpenSSLSocketImpl> clientFuture = handshake(listener, clientHooks);
-            Future<OpenSSLSocketImpl> serverFuture = handshake(listener, serverHooks);
+            Future<AbstractConscryptSocket> clientFuture = handshake(listener, clientHooks);
+            Future<AbstractConscryptSocket> serverFuture = handshake(listener, serverHooks);
 
             try {
                 client = getOrThrowCause(clientFuture, TIMEOUT_SECONDS, TimeUnit.SECONDS);
@@ -289,9 +290,9 @@
             }
         }
 
-        Future<OpenSSLSocketImpl> handshake(final ServerSocket listener, final Hooks hooks) {
+        Future<AbstractConscryptSocket> handshake(final ServerSocket listener, final Hooks hooks) {
             return executor.submit(() -> {
-                OpenSSLSocketImpl socket = hooks.createSocket(listener);
+                AbstractConscryptSocket socket = hooks.createSocket(listener);
                 socket.addHandshakeCompletedListener(hooks);
 
                 socket.startHandshake();
@@ -390,8 +391,8 @@
 
         connection.clientHooks = new ClientHooks() {
             @Override
-            public OpenSSLSocketImpl createSocket(ServerSocket listener) throws IOException {
-                OpenSSLSocketImpl socket = super.createSocket(listener);
+            public AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException {
+                AbstractConscryptSocket socket = super.createSocket(listener);
                 socket.setEnabledProtocols(new String[] {"SSLv3"});
                 assertEquals(
                         "SSLv3 should be filtered out", 0, socket.getEnabledProtocols().length);
diff --git a/openjdk/src/test/java/org/conscrypt/PlatformTest.java b/openjdk/src/test/java/org/conscrypt/PlatformTest.java
index 2afd99d..1d7ea75 100644
--- a/openjdk/src/test/java/org/conscrypt/PlatformTest.java
+++ b/openjdk/src/test/java/org/conscrypt/PlatformTest.java
@@ -37,8 +37,8 @@
         params.setServerNames(names);
         params.setUseCipherSuitesOrder(false);
         params.setEndpointIdentificationAlgorithm("ABC");
-        Platform.setSSLParameters(params, impl, (OpenSSLSocketImpl)socket);
-        assertEquals("some.host", ((OpenSSLSocketImpl)socket).getHostname());
+        Platform.setSSLParameters(params, impl, (AbstractConscryptSocket)socket);
+        assertEquals("some.host", ((AbstractConscryptSocket)socket).getHostname());
         assertFalse(impl.getUseCipherSuitesOrder());
         assertEquals("ABC", impl.getEndpointIdentificationAlgorithm());
     }
@@ -49,8 +49,8 @@
         SSLParameters params = new SSLParameters();
         impl.setUseCipherSuitesOrder(false);
         impl.setEndpointIdentificationAlgorithm("ABC");
-        ((OpenSSLSocketImpl)socket).setHostname("some.host");
-        Platform.getSSLParameters(params, impl, (OpenSSLSocketImpl)socket);
+        ((AbstractConscryptSocket)socket).setHostname("some.host");
+        Platform.getSSLParameters(params, impl, (AbstractConscryptSocket)socket);
         assertEquals("some.host", ((SNIHostName)params.getServerNames().get(0)).getAsciiName());
         assertFalse(params.getUseCipherSuitesOrder());
         assertEquals("ABC", params.getEndpointIdentificationAlgorithm());
diff --git a/platform/proguard-rules.pro b/platform/proguard-rules.pro
index c3bdd2c..3bc75b2 100644
--- a/platform/proguard-rules.pro
+++ b/platform/proguard-rules.pro
@@ -20,5 +20,7 @@
 -dontwarn dalvik.system.BlockGuard
 -dontwarn dalvik.system.BlockGuard$Policy
 -dontwarn dalvik.system.CloseGuard
+-dontwarn com.android.org.conscrypt.AbstractConscryptSocket
+-dontwarn com.android.org.conscrypt.ConscryptFileDescriptorSocket
 -dontwarn com.android.org.conscrypt.OpenSSLSocketImpl
 -dontwarn org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
diff --git a/platform/src/main/java/org/conscrypt/Platform.java b/platform/src/main/java/org/conscrypt/Platform.java
index 6a74a03..5a62468 100644
--- a/platform/src/main/java/org/conscrypt/Platform.java
+++ b/platform/src/main/java/org/conscrypt/Platform.java
@@ -75,11 +75,11 @@
         return s.getFileDescriptor$();
     }
 
-    static FileDescriptor getFileDescriptorFromSSLSocket(OpenSSLSocketImpl openSSLSocketImpl) {
+    static FileDescriptor getFileDescriptorFromSSLSocket(AbstractConscryptSocket socket) {
         try {
             Field f_impl = Socket.class.getDeclaredField("impl");
             f_impl.setAccessible(true);
-            Object socketImpl = f_impl.get(openSSLSocketImpl);
+            Object socketImpl = f_impl.get(socket);
             Field f_fd = SocketImpl.class.getDeclaredField("fd");
             f_fd.setAccessible(true);
             return (FileDescriptor) f_fd.get(socketImpl);
@@ -106,7 +106,7 @@
     }
 
     static void setSSLParameters(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket) {
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
         impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
         impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder());
         List<SNIServerName> serverNames = params.getServerNames();
@@ -121,7 +121,7 @@
     }
 
     static void getSSLParameters(
-            SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket) {
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
         params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
         params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder());
         if (impl.getUseSni() && AddressUtils.isValidSniHostname(socket.getHostname())) {
@@ -171,7 +171,7 @@
         } catch (NoSuchMethodException | IllegalAccessException ignored) {
         } catch (InvocationTargetException e) {
             if (e.getCause() instanceof CertificateException) {
-                throw (CertificateException) e.getCause();
+                throw(CertificateException) e.getCause();
             }
             throw new RuntimeException(e.getCause());
         }
@@ -179,7 +179,7 @@
     }
 
     static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
-            OpenSSLSocketImpl socket) throws CertificateException {
+            AbstractConscryptSocket socket) throws CertificateException {
         if (tm instanceof X509ExtendedTrustManager) {
             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
             x509etm.checkClientTrusted(chain, authType, socket);
@@ -191,7 +191,7 @@
     }
 
     static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
-            OpenSSLSocketImpl socket) throws CertificateException {
+            AbstractConscryptSocket socket) throws CertificateException {
         if (tm instanceof X509ExtendedTrustManager) {
             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
             x509etm.checkServerTrusted(chain, authType, socket);
