Merge f-team to m-c
authorWes Kocher <wkocher@mozilla.com>
Tue, 24 Dec 2013 15:18:28 -0800
changeset 161789 cd3e9359fd64de26b86c256c5f35f8dee61bda19
parent 161786 2082d32e58f7d00a279a80c5e40d6fe2121cb71e (current diff)
parent 161788 9bfd0ab40e7e6948b9f95ee0c3e5c50a61b88cc4 (diff)
child 161790 06125c2e28fb3dfd8e85d26dbb0db32555a56be4
child 161802 b0b40893a1b4dff26a6781363589669b890e8288
child 161804 2fb4ae8a01e99141240c812a08495db11911c2f7
push id37981
push userkwierso@gmail.com
push dateTue, 24 Dec 2013 23:25:36 +0000
treeherdermozilla-inbound@06125c2e28fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.0a1
first release with
nightly linux32
cd3e9359fd64 / 29.0a1 / 20131225030203 / files
nightly linux64
cd3e9359fd64 / 29.0a1 / 20131225030203 / files
nightly mac
cd3e9359fd64 / 29.0a1 / 20131225030203 / files
nightly win32
cd3e9359fd64 / 29.0a1 / 20131225030203 / files
nightly win64
cd3e9359fd64 / 29.0a1 / 20131225030203 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge f-team to m-c
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -22,22 +22,16 @@
                           accesskey="&newNavigatorCmd.accesskey;"
                           key="key_newNavigator"
                           command="cmd_newNavigator"/>
                 <menuitem id="menu_newPrivateWindow"
                           label="&newPrivateWindow.label;"
                           accesskey="&newPrivateWindow.accesskey;"
                           command="Tools:PrivateBrowsing"
                           key="key_privatebrowsing"/>
-                <menuitem id="menu_openLocation"
-                          class="show-only-for-keyboard"
-                          label="&openLocationCmd.label;"
-                          command="Browser:OpenLocation"
-                          key="focusURLBar"
-                          accesskey="&openLocationCmd.accesskey;"/>
                 <menuitem id="menu_openFile"
                           label="&openFileCmd.label;"
                           command="Browser:OpenFile"
                           key="openFileKb"
                           accesskey="&openFileCmd.accesskey;"/>
                 <menuitem id="menu_close"
                           class="show-only-for-keyboard"
                           label="&closeCmd.label;"
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -52,18 +52,16 @@ can reach it easily. -->
 <!ENTITY  closeTab.label                     "Close Tab">
 <!ENTITY  closeTab.accesskey                 "c">
 
 <!ENTITY  listAllTabs.label      "List all tabs">
 
 <!ENTITY tabCmd.label "New Tab">
 <!ENTITY tabCmd.accesskey "T">
 <!ENTITY tabCmd.commandkey "t">
-<!ENTITY openLocationCmd.label "Open Location…">
-<!ENTITY openLocationCmd.accesskey "L">
 <!ENTITY openFileCmd.label "Open File…">
 <!ENTITY openFileCmd.accesskey "O">
 <!ENTITY openFileCmd.commandkey "o">
 <!ENTITY printSetupCmd.label "Page Setup…">
 <!ENTITY printSetupCmd.accesskey "u">
 <!ENTITY printPreviewCmd.label "Print Preview">
 <!ENTITY printPreviewCmd.accesskey "v">
 <!ENTITY printCmd.label "Print…">
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -63,16 +63,17 @@ import android.net.Uri;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
 import android.os.SystemClock;
 import android.os.Vibrator;
 import android.provider.Settings;
+import android.support.v4.util.LruCache;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Base64;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.HapticFeedbackConstants;
 import android.view.Surface;
@@ -2657,49 +2658,94 @@ public class GeckoAppShell
         if (getGeckoInterface() != null) {
             GeckoProfile profile = getGeckoInterface().getProfile();
             File lock = profile.getFile(".parentlock");
             return lock.exists() && lock.delete();
         }
         return false;
     }
 
-    @WrapElementForJNI(stubName = "GetProxyForURIWrapper")
-    public static String getProxyForURI(String spec, String scheme, String host, int port) {
-        URI uri = null;
+    // Holds mappings from hostnames to URIs.
+    // We only use this for HTTP and HTTPS on default ports (-1), because it's
+    // simpler to do so while addressing most uses.
+    private static LruCache<String, URI> httpURIs = new LruCache<String, URI>(10);
+    private static LruCache<String, URI> httpsURIs = new LruCache<String, URI>(10);
+
+    private static URI getAndCacheURIByParts(String scheme, String host, LruCache<String, URI> cache) {
+        URI uri = cache.get(host);
+        if (uri != null) {
+            return uri;
+        }
+
         try {
-            uri = new URI(spec);
-        } catch(java.net.URISyntaxException uriEx) {
-            try {
-                uri = new URI(scheme, null, host, port, null, null, null);
-            } catch(java.net.URISyntaxException uriEx2) {
-                Log.d("GeckoProxy", "Failed to create uri from spec", uriEx);
-                Log.d("GeckoProxy", "Failed to create uri from parts", uriEx2);
+            uri = new URI(scheme, null, host, -1, null, null, null);
+        } catch (java.net.URISyntaxException uriEx) {
+            Log.d("GeckoProxy", "Failed to create URI from parts.", uriEx);
+            return null;
+        }
+
+        cache.put(host, uri);
+        return uri;
+    }
+
+    private static URI getURIByParts(String scheme, String host, int port) {
+        if (port == -1) {
+            if (scheme.equals("http")) {
+                return getAndCacheURIByParts("http", host, httpURIs);
+            } else if (scheme.equals("https")) {
+                return getAndCacheURIByParts("https", host, httpsURIs);
             }
         }
-        if (uri != null) {
-            ProxySelector ps = ProxySelector.getDefault();
-            if (ps != null) {
-                List<Proxy> proxies = ps.select(uri);
-                if (proxies != null && !proxies.isEmpty()) {
-                    Proxy proxy = proxies.get(0);
-                    if (!Proxy.NO_PROXY.equals(proxy)) {
-                        final String proxyStr;
-                        switch (proxy.type()) {
-                        case HTTP:
-                            proxyStr = "PROXY " + proxy.address().toString();
-                            break;
-                        case SOCKS:
-                            proxyStr = "SOCKS " + proxy.address().toString();
-                            break;
-                        case DIRECT:
-                        default:
-                            proxyStr = "DIRECT";
-                            break;
-                        }
-                        return proxyStr;
-                    }
-                }
-            }
+
+        try {
+            return new URI(scheme, null, host, port, null, null, null);
+        } catch (java.net.URISyntaxException uriEx) {
+            Log.d("GeckoProxy", "Failed to create URI from parts.", uriEx);
+        }
+
+        return null;
+    }
+
+    @WrapElementForJNI(stubName = "GetProxyForURIWrapper")
+    public static String getProxyForURI(String spec, String scheme, String host, int port) {
+        final ProxySelector ps;
+        try {
+            // This is cheap -- just a SecurityManager check and a static
+            // access inside ProxySelector.
+            ps = ProxySelector.getDefault();
+        } catch (SecurityException ex) {
+            Log.w(LOGTAG, "Not allowed to use default ProxySelector.");
+            return "DIRECT";
+        }
+
+        if (ps == null) {
+            return "DIRECT";
         }
+
+        // We don't use the whole spec because parsing a URI from a string
+        // is expensive, and the stock Android proxy behavior looks only at
+        // the scheme and host.
+        URI uri = getURIByParts(scheme, host, port);
+
+        if (uri == null) {
+            return "DIRECT";
+        }
+
+        List<Proxy> proxies = ps.select(uri);
+        if (proxies == null || proxies.isEmpty()) {
+            return "DIRECT";
+        }
+
+        Proxy proxy = proxies.get(0);
+        if (Proxy.NO_PROXY.equals(proxy)) {
+            return "DIRECT";
+        }
+        
+        switch (proxy.type()) {
+            case HTTP:
+                return "PROXY " + proxy.address().toString();
+            case SOCKS:
+                return "SOCKS " + proxy.address().toString();
+        }
+
         return "DIRECT";
     }
 }