Bug 762691 - Use single AndroidHttpClient for all favicon requests. r=mfinkle
authorBrian Nicholson <bnicholson@mozilla.com>
Thu, 07 Jun 2012 17:24:03 -0700
changeset 96131 4663263e6dd7488e7a600a55993d951f8b0db351
parent 96130 53f971a7b77b547c244ef135d66562141b2d6dbe
child 96132 ad8edddea8d397bd3e49381c530c90e90c7620f0
push id22875
push useremorley@mozilla.com
push dateFri, 08 Jun 2012 10:26:24 +0000
treeherdermozilla-central@22bb7d46bb23 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs762691
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 762691 - Use single AndroidHttpClient for all favicon requests. r=mfinkle
mobile/android/base/Favicons.java
--- a/mobile/android/base/Favicons.java
+++ b/mobile/android/base/Favicons.java
@@ -9,16 +9,17 @@ import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.net.http.AndroidHttpClient;
 import android.os.AsyncTask;
 import android.util.Log;
 
 import java.io.InputStream;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URI;
@@ -29,28 +30,29 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
 import org.mozilla.gecko.db.BrowserDB;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.entity.BufferedHttpEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
 
 public class Favicons {
     private static final String LOGTAG = "GeckoFavicons";
 
     public static final long NOT_LOADING = 0;
 
     private Context mContext;
     private DatabaseHelper mDbHelper;
 
     private Map<Long,LoadFaviconTask> mLoadTasks;
     private long mNextFaviconLoadId;
+    private static final String USER_AGENT = GeckoApp.mAppContext.getDefaultUAString();
+    private AndroidHttpClient mHttpClient;
 
     public interface OnFaviconLoadedListener {
         public void onFaviconLoaded(String url, Drawable favicon);
     }
 
     private class DatabaseHelper extends SQLiteOpenHelper {
         private static final String DATABASE_NAME = "favicon_urls.db";
         private static final String TABLE_NAME = "favicon_urls";
@@ -138,16 +140,24 @@ public class Favicons {
 
         mContext = context;
         mDbHelper = new DatabaseHelper(context);
 
         mLoadTasks = Collections.synchronizedMap(new HashMap<Long,LoadFaviconTask>());
         mNextFaviconLoadId = 0;
     }
 
+    private synchronized AndroidHttpClient getHttpClient() {
+        if (mHttpClient != null)
+            return mHttpClient;
+
+        mHttpClient = AndroidHttpClient.newInstance(USER_AGENT);
+        return mHttpClient;
+    }
+
     public long loadFavicon(String pageUrl, String faviconUrl,
             OnFaviconLoadedListener listener) {
 
         // Handle the case where page url is empty
         if (pageUrl == null || pageUrl.length() == 0) {
             if (listener != null)
                 listener.onFaviconLoaded(null, null);
         }
@@ -194,16 +204,18 @@ public class Favicons {
         synchronized (mLoadTasks) {
             Set<Long> taskIds = mLoadTasks.keySet();
             Iterator<Long> iter = taskIds.iterator();
             while (iter.hasNext()) {
                 long taskId = iter.next();
                 cancelFaviconLoad(taskId);
             }
         }
+        if (mHttpClient != null)
+            mHttpClient.close();
     }
 
     private class LoadFaviconTask extends AsyncTask<Void, Void, BitmapDrawable> {
         private long mId;
         private String mPageUrl;
         private String mFaviconUrl;
         private OnFaviconLoadedListener mListener;
 
@@ -267,32 +279,24 @@ public class Favicons {
             // only get favicons for HTTP/HTTPS
             String scheme = uri.getScheme();
             if (!"http".equals(scheme) && !"https".equals(scheme))
                 return null;
 
             // skia decoder sometimes returns null; workaround is to use BufferedHttpEntity
             // http://groups.google.com/group/android-developers/browse_thread/thread/171b8bf35dbbed96/c3ec5f45436ceec8?lnk=raot 
             BitmapDrawable image = null;
-            InputStream contentStream = null;
             try {
                 HttpGet request = new HttpGet(faviconUrl.toURI());
-                HttpEntity entity = new DefaultHttpClient().execute(request).getEntity();
+                HttpEntity entity = getHttpClient().execute(request).getEntity();
                 BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
-                contentStream = bufferedEntity.getContent();
+                InputStream contentStream = bufferedEntity.getContent();
                 image = (BitmapDrawable) Drawable.createFromStream(contentStream, "src");
             } catch (Exception e) {
                 Log.e(LOGTAG, "Error reading favicon", e);
-            } finally {
-                try {
-                    if (contentStream != null)
-                        contentStream.close();
-                } catch (IOException e) {
-                    Log.d(LOGTAG, "error closing favicon stream");
-                }
             }
 
             return image;
         }
 
         @Override
         protected BitmapDrawable doInBackground(Void... unused) {
             BitmapDrawable image = null;