Bug 704922 - Fix racy behaviour of bookmark checks in Tab (r=mfinkle)
authorLucas Rocha <lucasr@mozilla.com>
Mon, 16 Jan 2012 14:57:36 +0000
changeset 85816 82ee45c3759e10732d15d213b1eac46c80e5fc2b
parent 85815 48b579a0492519c08535360e11c1dc3337fe29a8
child 85817 ab470552b6f18008fa53d79fb0c6eb032fb129cf
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs704922
milestone12.0a1
Bug 704922 - Fix racy behaviour of bookmark checks in Tab (r=mfinkle)
mobile/android/base/Tab.java
--- a/mobile/android/base/Tab.java
+++ b/mobile/android/base/Tab.java
@@ -36,16 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 package org.mozilla.gecko;
 
 import android.content.ContentResolver;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.Bitmap;
+import android.os.AsyncTask;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.graphics.Bitmap;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.ByteArrayOutputStream;
@@ -72,16 +73,17 @@ public class Tab {
     private List<HistoryEntry> mHistory;
     private int mHistoryIndex;
     private int mParentId;
     private boolean mExternal;
     private boolean mLoading;
     private boolean mBookmark;
     private HashMap<String, DoorHanger> mDoorHangers;
     private long mFaviconLoadId;
+    private CheckBookmarkTask mCheckBookmarkTask;
     private String mDocumentURI;
     private String mContentType;
 
     static class HistoryEntry {
         public final String mUri;   // must never be null
         public String mTitle;       // must never be null
 
         public HistoryEntry(String uri, String title) {
@@ -269,17 +271,25 @@ public class Tab {
         Log.i(LOGTAG, "Updated favicon URL for tab with id: " + mId);
     }
 
     public void updateSecurityMode(String mode) {
         mSecurityMode = mode;
     }
 
     private void updateBookmark() {
-        new CheckBookmarkTask().execute();
+        GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
+            public void run() {
+                if (mCheckBookmarkTask != null)
+                    mCheckBookmarkTask.cancel(false);
+
+                mCheckBookmarkTask = new CheckBookmarkTask(getURL());
+                mCheckBookmarkTask.execute();
+            }
+        });
     }
 
     public void addBookmark() {
         new AddBookmarkTask().execute();
     }
 
     public void removeBookmark() {
         new RemoveBookmarkTask().execute();
@@ -389,26 +399,48 @@ public class Tab {
             }
             mHistoryIndex = index;
         } else if (event.equals("Purge")) {
             mHistory.clear();
             mHistoryIndex = -1;
         }
     }
 
-    private class CheckBookmarkTask extends GeckoAsyncTask<Void, Void, Boolean> {
+    private class CheckBookmarkTask extends AsyncTask<Void, Void, Boolean> {
+        private final String mUrl;
+
+        public CheckBookmarkTask(String url) {
+            mUrl = url;
+        }
+
         @Override
         protected Boolean doInBackground(Void... unused) {
             ContentResolver resolver = Tabs.getInstance().getContentResolver();
-            return BrowserDB.isBookmark(resolver, getURL());
+            return BrowserDB.isBookmark(resolver, mUrl);
+        }
+
+        @Override
+        protected void onCancelled() {
+            mCheckBookmarkTask = null;
         }
 
         @Override
-        protected void onPostExecute(Boolean isBookmark) {
-            setBookmark(isBookmark.booleanValue());
+        protected void onPostExecute(final Boolean isBookmark) {
+            mCheckBookmarkTask = null;
+
+            GeckoApp.mAppContext.runOnUiThread(new Runnable() {
+                public void run() {
+                    // Ignore this task if it's not about the current
+                    // tab URL anymore.
+                    if (!mUrl.equals(getURL()))
+                        return;
+
+                    setBookmark(isBookmark.booleanValue());
+                }
+            });
         }
     }
 
     private class AddBookmarkTask extends GeckoAsyncTask<Void, Void, Void> {
         @Override
         protected Void doInBackground(Void... unused) {
             ContentResolver resolver = Tabs.getInstance().getContentResolver();
             BrowserDB.addBookmark(resolver, getTitle(), getURL());