Add hack to make sure Socket#impl field is not null

Conscrypt's compat code inspects the "impl" field of Socket and expects
it to be non-null. However, SocketChannel creates an adaptor that sets
the impl field to non-null. This can't be fixed immediately, so put this
in to maintain the old behavior.

Bug: 25857624
Change-Id: I2d79a6d9a77d9102203cfb43df09d70aff99ffe3
diff --git a/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
index c901a08..f87cf4d 100644
--- a/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/SocketChannelTest.java
@@ -19,8 +19,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.reflect.Field;
 import java.net.ConnectException;
 import java.net.Socket;
+import java.net.SocketImpl;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
@@ -264,4 +266,14 @@
     ss.close();
     sc.close();
   }
+
+  public void test_Socket_impl_notNull() throws Exception {
+    SocketChannel sc = SocketChannel.open();
+    Socket socket = sc.socket();
+    Field f_impl = Socket.class.getDeclaredField("impl");
+    f_impl.setAccessible(true);
+    Object implFieldValue = f_impl.get(socket);
+    assertNotNull(implFieldValue);
+    assertTrue(implFieldValue instanceof SocketImpl);
+  }
 }
diff --git a/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java b/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
new file mode 100644
index 0000000..d7a9fc6
--- /dev/null
+++ b/ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project in the LICENSE
+ * file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package sun.nio.ch;
+
+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.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+
+/**
+ * This class is only used for {@link SocketAdaptor} to be backward-compatible
+ * with older Android versions which always set the {@code impl} field of
+ * {@link Socket}. As such none of the methods in this class are implemented
+ * since {@link SocketAdaptor} should override everything in {@link Socket}
+ * which may access the {@code impl} field.
+ */
+class FileDescriptorHolderSocketImpl extends SocketImpl {
+    public FileDescriptorHolderSocketImpl(FileDescriptor fd) {
+        this.fd = fd;
+    }
+
+    @Override
+    public void setOption(int optID, Object value) throws SocketException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Object getOption(int optID) throws SocketException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void create(boolean stream) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void connect(String host, int port) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void connect(InetAddress address, int port) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void connect(SocketAddress address, int timeout) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void bind(InetAddress host, int port) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void listen(int backlog) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void accept(SocketImpl s) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected InputStream getInputStream() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected OutputStream getOutputStream() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected int available() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void close() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void sendUrgentData(int data) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
index d2ebde5..4240aea 100755
--- a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
@@ -61,7 +61,7 @@
     private volatile int timeout = 0;
 
     private SocketAdaptor(SocketChannelImpl sc) throws SocketException {
-        super((SocketImpl) null);
+        super(new FileDescriptorHolderSocketImpl(sc.getFD()));
         this.sc = sc;
     }
 
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index 531c278..29f53aa 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1124,6 +1124,7 @@
     ojluni/src/main/java/sun/nio/ch/EPollSelectorProvider.java \
     ojluni/src/main/java/sun/nio/ch/ExtendedSocketOption.java \
     ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java \
+    ojluni/src/main/java/sun/nio/ch/FileDescriptorHolderSocketImpl.java \
     ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java \
     ojluni/src/main/java/sun/nio/ch/FileDispatcher.java \
     ojluni/src/main/java/sun/nio/ch/FileKey.java \