Bug 784500 - Start connection to passed in urls in java. r=blassey
authorWes Johnston <wjohnston@mozilla.com>
Mon, 27 Aug 2012 17:11:42 -0700
changeset 105653 38ca4f43a4fd6a3f33bf055895ab1965bb3f528c
parent 105652 1b3fa4309f3145d736a0a75762d9a1da7382d2c1
child 105654 8264b7d01a5abec721e01bdc8b85c52458e0a3b8
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersblassey
bugs784500
milestone18.0a1
Bug 784500 - Start connection to passed in urls in java. r=blassey
mobile/android/base/GeckoApp.java
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1594,27 +1594,30 @@ abstract public class GeckoApp
         boolean isExternalURL = passedUri != null && !passedUri.equals("about:home");
         initializeChrome(uri, isExternalURL);
 
         // Start migrating as early as possible, can do this in
         // parallel with Gecko load.
         checkMigrateProfile();
 
         Uri data = intent.getData();
-        if (data != null && "http".equals(data.getScheme()) &&
-            isHostOnPrefetchWhitelist(data.getHost())) {
+        if (data != null && "http".equals(data.getScheme())) {
             Intent copy = new Intent(intent);
             copy.setAction(ACTION_LOAD);
-            GeckoAppShell.getHandler().post(new RedirectorRunnable(copy));
-            // We're going to handle this uri with the redirector, so setting
-            // the action to MAIN and clearing the uri data prevents us from
-            // loading it twice
-            intent.setAction(Intent.ACTION_MAIN);
-            intent.setData(null);
-            passedUri = "about:empty";
+            if (isHostOnRedirectWhitelist(data.getHost())) {
+                GeckoAppShell.getHandler().post(new RedirectorRunnable(copy));
+                // We're going to handle this uri with the redirector, so setting
+                // the action to MAIN and clearing the uri data prevents us from
+                // loading it twice
+                intent.setAction(Intent.ACTION_MAIN);
+                intent.setData(null);
+                passedUri = "about:empty";
+            } else {
+                GeckoAppShell.getHandler().post(new PrefetchRunnable(copy));
+            }
         }
 
         if (!mIsRestoringActivity) {
             sGeckoThread = new GeckoThread(intent, passedUri, mRestoreMode);
         }
         if (!ACTION_DEBUG.equals(action) &&
             checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched)) {
             sGeckoThread.start();
@@ -1782,80 +1785,99 @@ abstract public class GeckoApp
 
     public void disableCameraView() {
         mMainLayout.removeView(cameraView);
     }
 
     abstract public String getDefaultUAString();
     abstract public String getUAStringForHost(String host);
 
-    class RedirectorRunnable implements Runnable {
+    class PrefetchRunnable implements Runnable {
         Intent mIntent;
-        RedirectorRunnable(Intent intent) {
+        protected HttpURLConnection mConnection = null;
+        PrefetchRunnable(Intent intent) {
             mIntent = intent;
         }
+
+        private void afterLoad() { }
+
         public void run() {
-            HttpURLConnection connection = null;
             try {
                 // this class should only be initialized with an intent with non-null data
                 URL url = new URL(mIntent.getData().toString());
+                Log.i(LOGTAG, "xxx - Loading: " + url);
                 // data url should have an http scheme
-                connection = (HttpURLConnection) url.openConnection();
-                connection.setRequestProperty("User-Agent", getUAStringForHost(url.getHost()));
-                connection.setInstanceFollowRedirects(false);
-                connection.setRequestMethod("GET");
-                connection.connect();
-                int code = connection.getResponseCode();
+                mConnection = (HttpURLConnection) url.openConnection();
+                mConnection.setRequestProperty("User-Agent", getUAStringForHost(url.getHost()));
+                mConnection.setInstanceFollowRedirects(false);
+                mConnection.setRequestMethod("GET");
+                mConnection.connect();
+                afterLoad();
+            } catch (Exception e) {
+                Log.w(LOGTAG, "unexpected exception, passing url directly to Gecko but we should explicitly catch this", e);
+                mIntent.putExtra("prefetched", 1);
+            } finally {
+                if (mConnection != null)
+                    mConnection.disconnect();
+            }
+        }
+    }
+
+    class RedirectorRunnable extends PrefetchRunnable {
+        RedirectorRunnable(Intent intent) {
+            super(intent);
+        }
+        private void afterLoad() {
+            try {
+                int code = mConnection.getResponseCode();
                 if (code >= 300 && code < 400) {
-                    String location = connection.getHeaderField("Location");
+                    String location = mConnection.getHeaderField("Location");
                     Uri data;
                     if (location != null &&
                         (data = Uri.parse(location)) != null &&
                         !"about".equals(data.getScheme()) && 
                         !"chrome".equals(data.getScheme())) {
                         mIntent.setData(data);
                     } else {
                         mIntent.putExtra("prefetched", 1);
                     }
                 } else {
                     mIntent.putExtra("prefetched", 1);
                 }
             } catch (IOException ioe) {
                 Log.i(LOGTAG, "exception trying to pre-fetch redirected url", ioe);
                 mIntent.putExtra("prefetched", 1);
-            } catch (Exception e) {
-                Log.w(LOGTAG, "unexpected exception, passing url directly to Gecko but we should explicitly catch this", e);
-                mIntent.putExtra("prefetched", 1);
-            } finally {
-                if (connection != null)
-                    connection.disconnect();
             }
+        }
+        public void run() {
+            super.run();
+
             mMainHandler.postAtFrontOfQueue(new Runnable() {
                 public void run() {
                     onNewIntent(mIntent);
                 }
             });
         }
     }
 
-    private final String kPrefetchWhiteListArray[] = new String[] { 
+    private final String kRedirectWhiteListArray[] = new String[] { 
         "t.co",
         "bit.ly",
         "moz.la",
         "aje.me",
         "facebook.com",
         "goo.gl",
         "tinyurl.com"
     };
     
-    private final CopyOnWriteArrayList<String> kPrefetchWhiteList =
-        new CopyOnWriteArrayList<String>(kPrefetchWhiteListArray);
-
-    private boolean isHostOnPrefetchWhitelist(String host) {
-        return kPrefetchWhiteList.contains(host);
+    private final CopyOnWriteArrayList<String> kRedirectWhiteList =
+        new CopyOnWriteArrayList<String>(kRedirectWhiteListArray);
+
+    private boolean isHostOnRedirectWhitelist(String host) {
+        return kRedirectWhiteList.contains(host);
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onNewIntent");
 
         if (checkLaunchState(LaunchState.GeckoExiting)) {
             // We're exiting and shouldn't try to do anything else just incase
@@ -1879,20 +1901,23 @@ abstract public class GeckoApp
             Uri data = intent.getData();
             Bundle bundle = intent.getExtras();
             // if the intent has data (i.e. a URI to be opened) and the scheme
             // is either http, we'll prefetch it, which means warming
             // up the radio and DNS cache by connecting and parsing the redirect
             // if the return code is between 300 and 400
             if (data != null && 
                 "http".equals(data.getScheme()) &&
-                (bundle == null || bundle.getInt("prefetched", 0) != 1) &&
-                isHostOnPrefetchWhitelist(data.getHost())) {
-                GeckoAppShell.getHandler().post(new RedirectorRunnable(intent));
-                return;
+                (bundle == null || bundle.getInt("prefetched", 0) != 1)) {
+                if (isHostOnRedirectWhitelist(data.getHost())) {
+                    GeckoAppShell.getHandler().post(new RedirectorRunnable(intent));
+                    return;
+                } else {
+                    GeckoAppShell.getHandler().post(new PrefetchRunnable(intent));
+                }
             }
         }
         final String action = intent.getAction();
 
         if (Intent.ACTION_MAIN.equals(action)) {
             Log.i(LOGTAG, "Intent : ACTION_MAIN");
             GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(""));
         }