am e87d36f8: Merge "Revert "Remove unused apache related API.""

* commit 'e87d36f8925a34f85ba80c886757d07ad03fed42':
  Revert "Remove unused apache related API."
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index c391eb8..418093b 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -23,9 +23,18 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.conn.routing.HttpRoutePlanner;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.protocol.HttpContext;
+
 import java.net.InetSocketAddress;
 import java.net.ProxySelector;
 import java.net.URI;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -35,6 +44,8 @@
  */
 public final class Proxy {
 
+    // Set to true to enable extra debugging.
+    private static final boolean DEBUG = false;
     private static final String TAG = "Proxy";
 
     private static final ProxySelector sDefaultProxySelector;
@@ -188,6 +199,30 @@
         }
     }
 
+    /**
+     * Returns the preferred proxy to be used by clients. This is a wrapper
+     * around {@link android.net.Proxy#getHost()}.
+     *
+     * @param context the context which will be passed to
+     * {@link android.net.Proxy#getHost()}
+     * @param url the target URL for the request
+     * @note Calling this method requires permission
+     * android.permission.ACCESS_NETWORK_STATE
+     * @return The preferred proxy to be used by clients, or null if there
+     * is no proxy.
+     * {@hide}
+     */
+    public static final HttpHost getPreferredHttpHost(Context context,
+            String url) {
+        java.net.Proxy prefProxy = getProxy(context, url);
+        if (prefProxy.equals(java.net.Proxy.NO_PROXY)) {
+            return null;
+        } else {
+            InetSocketAddress sa = (InetSocketAddress)prefProxy.address();
+            return new HttpHost(sa.getHostName(), sa.getPort(), "http");
+        }
+    }
+
     private static final boolean isLocalHost(String host) {
         if (host == null) {
             return false;
@@ -233,6 +268,48 @@
         return PROXY_VALID;
     }
 
+    static class AndroidProxySelectorRoutePlanner
+            extends org.apache.http.impl.conn.ProxySelectorRoutePlanner {
+
+        private Context mContext;
+
+        public AndroidProxySelectorRoutePlanner(SchemeRegistry schreg, ProxySelector prosel,
+                Context context) {
+            super(schreg, prosel);
+            mContext = context;
+        }
+
+        @Override
+        protected java.net.Proxy chooseProxy(List<java.net.Proxy> proxies, HttpHost target,
+                HttpRequest request, HttpContext context) {
+            return getProxy(mContext, target.getHostName());
+        }
+
+        @Override
+        protected HttpHost determineProxy(HttpHost target, HttpRequest request,
+                HttpContext context) {
+            return getPreferredHttpHost(mContext, target.getHostName());
+        }
+
+        @Override
+        public HttpRoute determineRoute(HttpHost target, HttpRequest request,
+                HttpContext context) {
+            HttpHost proxy = getPreferredHttpHost(mContext, target.getHostName());
+            if (proxy == null) {
+                return new HttpRoute(target);
+            } else {
+                return new HttpRoute(target, null, proxy, false);
+            }
+        }
+    }
+
+    /** @hide */
+    public static final HttpRoutePlanner getAndroidProxySelectorRoutePlanner(Context context) {
+        AndroidProxySelectorRoutePlanner ret = new AndroidProxySelectorRoutePlanner(
+                new SchemeRegistry(), ProxySelector.getDefault(), context);
+        return ret;
+    }
+
     /** @hide */
     public static final void setHttpProxySystemProperty(ProxyInfo p) {
         String host = null;
diff --git a/tests/CoreTests/android/core/ProxyTest.java b/tests/CoreTests/android/core/ProxyTest.java
new file mode 100644
index 0000000..12acfe8
--- /dev/null
+++ b/tests/CoreTests/android/core/ProxyTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 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 android.core;
+
+import org.apache.http.HttpHost;
+
+import android.content.Context;
+import android.net.Proxy;
+import android.test.AndroidTestCase;
+
+/**
+ * Proxy tests
+ */
+public class ProxyTest extends AndroidTestCase {
+    private Context mContext;
+    private HttpHost mHttpHost;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getContext();
+        mHttpHost = null;
+        String proxyHost = Proxy.getHost(mContext);
+        int proxyPort = Proxy.getPort(mContext);
+        if (proxyHost != null) {
+            mHttpHost = new HttpHost(proxyHost, proxyPort, "http");
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Bad url parameter should not cause any exception.
+     */
+    public void testProxyGetPreferredHttpHost_UrlBad() throws Exception {
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, null));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, ""));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:\\"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad://#"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "://#"));
+    }
+
+    /**
+     * Proxy (if available) should be returned when url parameter is not localhost.
+     */
+    public void testProxyGetPreferredHttpHost_UrlNotlLocalhost() throws Exception {
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com/"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://192.168.0.1/"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "file:///foo/bar"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com/"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "javascript:alert(1)"));
+    }
+
+    /**
+     * No proxy should be returned when url parameter is localhost.
+     */
+    public void testProxyGetPreferredHttpHost_UrlLocalhost() throws Exception {
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/hej.html"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/hej.html"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:80/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:8080/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://127.0.0.1/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://localhost/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "https://localhost/"));
+    }
+}