Add makefile + jarjar rule for okhttp.

Created a new path android/ that contains android
specific patches to this code. This is not a long term approach,
simply a stop gap measure to get this codebase compiling and usable
under android. For now, this path contains changes to Libcore.java
to remove OpenJDK dependencies.

This patchset also updates the snapshot to upstream revision
2a05f0e18f0ae67.

Change-Id: Ic1ef8245109e07c7cf9f59c1e7881b86d357d74f
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..a24d43f
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2012 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := okhttp
+LOCAL_MODULE_TAGS := optional
+
+# Include all files under our snapshot except for Libcore.java
+# because it contains OpenJDK dependencies. This file is replaced
+# by an android specific version, see below.
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
+LOCAL_SRC_FILES := $(filter-out %/Libcore.java, $(LOCAL_SRC_FILES))
+
+LOCAL_SRC_FILES += $(call all-java-files-under, android/main/java)
+
+LOCAL_JARJAR_RULES := ${LOCAL_PATH}/jarjar-rules.txt
+include $(BUILD_JAVA_LIBRARY)
diff --git a/README.android b/README.android
index 7ce5ec6..636c351 100644
--- a/README.android
+++ b/README.android
@@ -2,3 +2,7 @@
 License: Apache 2
 Description: "OkHttp: An HTTP+SPDY client for Android and Java applications."
 
+Local patches
+-------------
+Changes to libcore/util/Libcore.java to remove OpenJDK / Jetty dependencies.
+
diff --git a/android/main/java/libcore/util/Libcore.java b/android/main/java/libcore/util/Libcore.java
new file mode 100644
index 0000000..e617b81
--- /dev/null
+++ b/android/main/java/libcore/util/Libcore.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 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 libcore.util;
+
+import javax.net.ssl.SSLSocket;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.ByteOrder;
+
+/**
+ * APIs for interacting with Android's core library. The main purpose of this
+ * class is to access hidden methods on
+ *
+ * org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
+ *
+ * via reflection.
+ */
+public final class Libcore {
+
+    private Libcore() {
+    }
+
+    private static final Class<?> openSslSocketClass;
+    private static final Method setEnabledCompressionMethods;
+    private static final Method setUseSessionTickets;
+    private static final Method setHostname;
+    private static final Method setNpnProtocols;
+    private static final Method getNpnSelectedProtocol;
+
+    static {
+        try {
+            openSslSocketClass = Class.forName(
+                    "org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl");
+            setEnabledCompressionMethods = openSslSocketClass.getMethod(
+                    "setEnabledCompressionMethods", String[].class);
+            setUseSessionTickets = openSslSocketClass.getMethod(
+                    "setUseSessionTickets", boolean.class);
+            setHostname = openSslSocketClass.getMethod("setHostname", String.class);
+            setNpnProtocols = openSslSocketClass.getMethod("setNpnProtocols", byte[].class);
+            getNpnSelectedProtocol = openSslSocketClass.getMethod("getNpnSelectedProtocol");
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException(cnfe);
+        } catch (NoSuchMethodException nsme) {
+            throw new RuntimeException(nsme);
+        }
+    }
+
+    public static void makeTlsTolerant(SSLSocket socket, String socketHost, boolean tlsTolerant) {
+        if (!tlsTolerant) {
+            socket.setEnabledProtocols(new String[] {"SSLv3"});
+            return;
+        }
+
+        if (openSslSocketClass.isInstance(socket)) {
+            try {
+                String[] compressionMethods = {"ZLIB"};
+                setEnabledCompressionMethods.invoke(socket,
+                        new Object[] {compressionMethods});
+                setUseSessionTickets.invoke(socket, true);
+                setHostname.invoke(socket, socketHost);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
+            } catch (IllegalAccessException e) {
+                throw new AssertionError(e);
+            }
+        } else {
+            throw new RuntimeException("Unknown socket implementation.");
+        }
+    }
+
+    /**
+     * Returns the negotiated protocol, or null if no protocol was negotiated.
+     */
+    public static byte[] getNpnSelectedProtocol(SSLSocket socket) {
+        if (openSslSocketClass.isInstance(socket)) {
+            try {
+                return (byte[]) getNpnSelectedProtocol.invoke(socket);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
+            } catch (IllegalAccessException e) {
+                throw new AssertionError(e);
+            }
+        } else {
+            throw new RuntimeException("Unknown socket implementation.");
+        }
+    }
+
+    public static void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) {
+        if (openSslSocketClass.isInstance(socket)) {
+            try {
+                setNpnProtocols.invoke(socket, new Object[] {npnProtocols});
+            } catch (IllegalAccessException e) {
+                throw new AssertionError(e);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            throw new RuntimeException("Unknown socket implementation.");
+        }
+    }
+
+    public static void deleteIfExists(File file) throws IOException {
+        // okhttp-changed: was Libcore.os.remove() in a try/catch block
+        file.delete();
+    }
+
+    public static void logW(String warning) {
+        // okhttp-changed: was System.logw()
+        System.out.println(warning);
+    }
+
+    public static int getEffectivePort(URI uri) {
+        return getEffectivePort(uri.getScheme(), uri.getPort());
+    }
+
+    public static int getEffectivePort(URL url) {
+        return getEffectivePort(url.getProtocol(), url.getPort());
+    }
+
+    private static int getEffectivePort(String scheme, int specifiedPort) {
+        if (specifiedPort != -1) {
+            return specifiedPort;
+        }
+
+        if ("http".equalsIgnoreCase(scheme)) {
+            return 80;
+        } else if ("https".equalsIgnoreCase(scheme)) {
+            return 443;
+        } else {
+            return -1;
+        }
+    }
+
+    public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
+        if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    public static void tagSocket(Socket socket) {
+    }
+
+    public static void untagSocket(Socket socket) throws SocketException {
+    }
+
+    public static URI toUriLenient(URL url) throws URISyntaxException {
+        return url.toURI(); // this isn't as good as the built-in toUriLenient
+    }
+
+    public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) {
+        if (order == ByteOrder.BIG_ENDIAN) {
+            dst[offset++] = (byte) ((value >> 24) & 0xff);
+            dst[offset++] = (byte) ((value >> 16) & 0xff);
+            dst[offset++] = (byte) ((value >>  8) & 0xff);
+            dst[offset  ] = (byte) ((value >>  0) & 0xff);
+        } else {
+            dst[offset++] = (byte) ((value >>  0) & 0xff);
+            dst[offset++] = (byte) ((value >>  8) & 0xff);
+            dst[offset++] = (byte) ((value >> 16) & 0xff);
+            dst[offset  ] = (byte) ((value >> 24) & 0xff);
+        }
+    }
+}
diff --git a/jarjar-rules.txt b/jarjar-rules.txt
new file mode 100644
index 0000000..83c5233
--- /dev/null
+++ b/jarjar-rules.txt
@@ -0,0 +1 @@
+rule libcore.** libcoreunbundled.@1
diff --git a/src/main/java/libcore/util/Libcore.java b/src/main/java/libcore/util/Libcore.java
index 740d678..0d7db0d 100644
--- a/src/main/java/libcore/util/Libcore.java
+++ b/src/main/java/libcore/util/Libcore.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2012 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 libcore.util;
 
 import java.io.File;