Merge "Clear cursor when switching between accounts" into jb-ub-mail
diff --git a/src/com/android/mail/browse/ConversationCursor.java b/src/com/android/mail/browse/ConversationCursor.java
index cc03604..5ba886d 100644
--- a/src/com/android/mail/browse/ConversationCursor.java
+++ b/src/com/android/mail/browse/ConversationCursor.java
@@ -28,11 +28,11 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.database.CursorWrapper;
-import android.database.DataSetObservable;
 import android.database.DataSetObserver;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.util.Log;
@@ -79,8 +79,6 @@
     @VisibleForTesting
     static ConversationProvider sProvider;
 
-    // The cursor instantiator's activity
-    private Activity mActivity;
     // The cursor underlying the caching cursor
     @VisibleForTesting
     Wrapper mUnderlyingCursor;
@@ -140,14 +138,13 @@
 
     public ConversationCursor(Activity activity, Uri uri, boolean initialConversationLimit,
             String name) {
-        //sActivity = activity;
         mInitialConversationLimit = initialConversationLimit;
         sResolver = activity.getContentResolver();
         sUriColumnIndex = UIProvider.CONVERSATION_URI_COLUMN;
         qUri = uri;
         mName = name;
         qProjection = UIProvider.CONVERSATION_PROJECTION;
-        mCursorObserver = new CursorObserver();
+        mCursorObserver = new CursorObserver(new Handler(Looper.getMainLooper()));
     }
 
     /**
@@ -271,9 +268,6 @@
     }
 
     private Wrapper doQuery(boolean withLimit) {
-        if (sResolver == null) {
-            sResolver = mActivity.getContentResolver();
-        }
         Uri uri = qUri;
         if (withLimit) {
             uri = uri.buildUpon().appendQueryParameter(ConversationListQueryParameters.LIMIT,
@@ -353,21 +347,21 @@
                     iter.remove();
                 }
             }
-        }
 
-        // Swap cursor
-        if (mUnderlyingCursor != null) {
-            close();
-        }
-        mUnderlyingCursor = newCursor;
+            // Swap cursor
+            if (mUnderlyingCursor != null) {
+                close();
+            }
+            mUnderlyingCursor = newCursor;
 
-        mPosition = -1;
-        mUnderlyingCursor.moveToPosition(mPosition);
-        if (!mCursorObserverRegistered) {
-            mUnderlyingCursor.registerContentObserver(mCursorObserver);
-            mCursorObserverRegistered = true;
+            mPosition = -1;
+            mUnderlyingCursor.moveToPosition(mPosition);
+            if (!mCursorObserverRegistered) {
+                mUnderlyingCursor.registerContentObserver(mCursorObserver);
+                mCursorObserverRegistered = true;
+            }
+            mRefreshRequired = false;
         }
-        mRefreshRequired = false;
     }
 
     /**
@@ -539,15 +533,15 @@
      * When the underlying cursor changes, we want to alert the listener
      */
     private void underlyingChanged() {
-        if (mCursorObserverRegistered) {
-            try {
-                mUnderlyingCursor.unregisterContentObserver(mCursorObserver);
-            } catch (IllegalStateException e) {
-                // Maybe the cursor was GC'd?
-            }
-            mCursorObserverRegistered = false;
-        }
         synchronized(mCacheMapLock) {
+            if (mCursorObserverRegistered) {
+                try {
+                    mUnderlyingCursor.unregisterContentObserver(mCursorObserver);
+                } catch (IllegalStateException e) {
+                    // Maybe the cursor was GC'd?
+                }
+                mCursorObserverRegistered = false;
+            }
             mRefreshRequired = true;
             if (!mPaused) {
                 notifyRefreshRequired();
@@ -604,8 +598,7 @@
      * Put the refreshed cursor in place (called by the UI)
      */
     public void sync() {
-        final Wrapper requeryCursor = mRequeryCursor;
-        if (requeryCursor == null) {
+        if (mRequeryCursor == null) {
             // This can happen during an animated deletion, if the UI isn't keeping track, or
             // if a new query intervened (i.e. user changed folders)
             if (DEBUG) {
@@ -613,16 +606,15 @@
             }
             return;
         }
-        if (DEBUG) {
-            LogUtils.i(TAG, "[sync() %s]", mName);
-        }
         synchronized(mCacheMapLock) {
+            if (DEBUG) {
+                LogUtils.i(TAG, "[sync() %s]", mName);
+            }
+            resetCursor(mRequeryCursor);
             mRequeryCursor = null;
             mRefreshTask = null;
             mRefreshReady = false;
         }
-        resetCursor(requeryCursor);
-
         notifyDataChanged();
     }
 
@@ -896,14 +888,14 @@
      * Observer of changes to underlying data
      */
     private class CursorObserver extends ContentObserver {
-        public CursorObserver() {
-            super(null);
+        public CursorObserver(Handler handler) {
+            super(handler);
         }
 
         @Override
         public void onChange(boolean selfChange) {
             // If we're here, then something outside of the UI has changed the data, and we
-            // must query the underlying provider for that data
+            // must query the underlying provider for that data;
             ConversationCursor.this.underlyingChanged();
         }
     }
diff --git a/src/com/android/mail/browse/SelectedConversationsActionMenu.java b/src/com/android/mail/browse/SelectedConversationsActionMenu.java
index 82b472b..39654d1 100644
--- a/src/com/android/mail/browse/SelectedConversationsActionMenu.java
+++ b/src/com/android/mail/browse/SelectedConversationsActionMenu.java
@@ -377,7 +377,7 @@
         final MenuItem archive = menu.findItem(R.id.archive);
         boolean showArchive =
                 mAccount.supportsCapability(UIProvider.AccountCapabilities.ARCHIVE)
-                && mFolder.supportsCapability(FolderCapabilities.ARCHIVE) && !mFolder.isTrash();
+                && mFolder.supportsCapability(FolderCapabilities.ARCHIVE);
         if (archive == null) {
             showArchive = false;
         } else {
@@ -413,7 +413,8 @@
         markNotImportant.setVisible(!showMarkImportant
                 && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
         final MenuItem trash = menu.findItem(R.id.delete);
-        trash.setVisible(!mFolder.isTrash());
+        trash.setVisible(mFolder != null
+                && mFolder.supportsCapability(UIProvider.FolderCapabilities.DELETE));
         return true;
     }
 
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 6710b33..1d0c692 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -398,7 +398,9 @@
                 && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
         Utils.setMenuItemVisibility(menu, R.id.mark_not_important, !showMarkImportant
                 && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
-        Utils.setMenuItemVisibility(menu, R.id.delete, mFolder != null && !mFolder.isTrash());
+        Utils.setMenuItemVisibility(menu, R.id.delete,
+                mFolder != null && mFolder.supportsCapability(
+                        UIProvider.FolderCapabilities.DELETE));
         final boolean archiveVisible = mAccount.supportsCapability(AccountCapabilities.ARCHIVE)
                 && mFolder != null && mFolder.supportsCapability(FolderCapabilities.ARCHIVE)
                 && !mFolder.isTrash();