Recent folders on tablet in conversation view only.

Fix b/5892452

There are two changes in this:

1. Allow suppression of recent folders, the header and the "Show all
   labels" footer.  2. Introduce a dead header to satisfy
   actionBar.setSelectedNavigationItem, so that we can receive taps on
   every visible account and folder. It is an empty, invisible view
   that is shown above all the accounts. The user cannot tap on it,
   and the user cannot see it. I'm not proud of this hack. We should
   request the framework team to add a setNavigationNone for such
   use-cases.

Change-Id: I83ec4bbb9bbac02941bb5d43a123a65e0afcb7f9
diff --git a/res/layout/empty.xml b/res/layout/empty.xml
new file mode 100644
index 0000000..faa5df7
--- /dev/null
+++ b/res/layout/empty.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2011 Google Inc.
+     Licensed to The Android Open Source Project.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+      android:layout_alignParentTop="true"
+      android:layout_alignParentRight="true"
+      android:layout_height="wrap_content"
+      android:layout_width="wrap_content"
+      >
+</View>
diff --git a/src/com/android/mail/AccountSpinnerAdapter.java b/src/com/android/mail/AccountSpinnerAdapter.java
index f8bab03..c3188e9 100644
--- a/src/com/android/mail/AccountSpinnerAdapter.java
+++ b/src/com/android/mail/AccountSpinnerAdapter.java
@@ -73,11 +73,16 @@
      * Boolean indicating whether the "Show All Folders" items should be shown
      */
     private final boolean mShowAllFoldersItem;
+    /**
+     * Set to true to enable recent folders, false to disable.
+     */
+    private boolean mRecentFoldersVisible;
 
     /** The folder currently being viewed */
     private Folder mCurrentFolder;
     private Context mContext;
 
+    private static final int TYPE_DEAD_HEADER = -1;
     public static final int TYPE_ACCOUNT = 0;
     public static final int TYPE_HEADER = 1;
     public static final int TYPE_FOLDER = 2;
@@ -93,31 +98,41 @@
      * {@link #TYPE_FOLDER}.
      */
     public int getType(int position) {
+        if (position == 0) {
+            return TYPE_DEAD_HEADER;
+        }
         // First the accounts
-        if (position < mNumAccounts) {
+        if (position <= mNumAccounts) {
             return TYPE_ACCOUNT;
         }
         // Then the header
-        if (position == mNumAccounts) {
+        if (position == mNumAccounts + 1) {
             return TYPE_HEADER;
         }
-        if (mShowAllFoldersItem) {
-            // The first few positions have accounts, and then the header.
-            final int offset = position - mNumAccounts - 1;
-            if (offset >= mRecentFolderList.size()) {
-                return TYPE_ALL_FOLDERS;
-            }
+        if (mShowAllFoldersItem && getRecentOffset(position) >= mRecentFolderList.size()) {
+            return TYPE_ALL_FOLDERS;
         }
         // Finally, the recent folders.
         return TYPE_FOLDER;
     }
 
     /**
+     * Given a position in the list, what offset does it correspond to in the Recent Folders
+     * list?
+     * @param position
+     * @return
+     */
+    private final int getRecentOffset(int position) {
+        return position - mNumAccounts - 2;
+    }
+
+    /**
      * Returns the position of the dead, unselectable element in the spinner.
      * @return
      */
-    public int getSpacerPosition() {
-        return mNumAccounts;
+    public final int getSpacerPosition() {
+        // Return the position of the dead header, which is always at the top.
+        return 0;
     }
 
     /**
@@ -208,14 +223,18 @@
 
     @Override
     public int getCount() {
-        // All the accounts, plus one header, plus recent folders, plus one if the
+        // If the recent folders are visible, then one header, recent folders, plus one if the
         // "show all folders" item should be shown
-        return mNumAccounts + 1 + mRecentFolderList.size() + (mShowAllFoldersItem ? 1 : 0);
+        final int numFolders = mRecentFoldersVisible ?
+                (1 + mRecentFolderList.size() + (mShowAllFoldersItem ? 1 : 0)) : 0;
+        return 1 + mNumAccounts + numFolders;
     }
 
     @Override
     public Object getItem(int position) {
         switch (getType(position)){
+            case TYPE_DEAD_HEADER:
+                return "dead header";
             case TYPE_ACCOUNT:
                 return getAccount(position);
             case TYPE_HEADER:
@@ -223,10 +242,8 @@
             case TYPE_ALL_FOLDERS:
                 return "show all folders";
             default:
-                // The first few positions have accounts, and then the header.
-                final int offset = position - mNumAccounts - 1;
                 // Return the folder at this location.
-                return mRecentFolderList.get(offset);
+                return mRecentFolderList.get(getRecentOffset(position));
         }
     }
 
@@ -283,8 +300,11 @@
 
     @Override
     public int getViewTypeCount() {
-        // Two views, and one header, and potentially one "show all folders" item
-        return 3 + (mShowAllFoldersItem ? 1 : 0);
+        // If recent folders are shown, then two views: Recent folders and a header, and potentially
+        // one "show all folders" item.
+        final int folderTypes = mRecentFoldersVisible ?  (2 + (mShowAllFoldersItem ? 1 : 0)) : 0;
+        // Accounts are the type of view always shown.
+        return 2 + folderTypes;
     }
 
     @Override
@@ -308,6 +328,15 @@
         int color = 0;
         int unreadCount = 0;
         switch (getType(position)) {
+            case TYPE_DEAD_HEADER:
+                convertView = mInflater.inflate(R.layout.empty, null);
+                return convertView;
+            case TYPE_ACCOUNT:
+                // TODO(viki): Get real Inbox or Priority Inbox using the URI. Remove ugly hack.
+                bigText = "Inbox";
+                smallText = getAccountFolder(position);
+                color = getAccountColor(position);
+                break;
             case TYPE_HEADER:
                 convertView = mInflater.inflate(R.layout.account_switch_spinner_dropdown_header,
                         null);
@@ -318,15 +347,8 @@
                     accountLabel.setText(label);
                 }
                 return convertView;
-            case TYPE_ACCOUNT:
-                // TODO(viki): Get real Inbox or Priority Inbox using the URI. Remove ugly hack.
-                bigText = "Inbox";
-                smallText = getAccountFolder(position);
-                color = getAccountColor(position);
-                break;
             case TYPE_FOLDER:
-                final int offset = position - mNumAccounts - 1;
-                final Folder folder = mRecentFolderList.get(offset);
+                final Folder folder = mRecentFolderList.get(getRecentOffset(position));
                 bigText = folder.name;
                 unreadCount = folder.unreadCount;
                 break;
@@ -379,10 +401,10 @@
      * @return the folder of the account at the given position.
      */
     private String getAccountFolder(int position) {
-        if (position >= mNumAccounts) {
+        if (position >= mNumAccounts + 1) {
             return "";
         }
-        return mAllAccounts[position].name;
+        return mAllAccounts[position - 1].name;
     }
 
     /**
@@ -391,10 +413,10 @@
      * @return the folder of the account at the given position.
      */
     private int getAccountColor(int position) {
-        if (position >= mNumAccounts) {
+        if (position >= mNumAccounts + 1) {
             return 0;
         }
-        return mAllAccounts[position].color;
+        return mAllAccounts[position - 1].color;
     }
 
     /**
@@ -403,14 +425,15 @@
      * @return the account at the given position.
      */
     private Account getAccount(int position) {
-        return mAllAccounts[position];
+        return mAllAccounts[position - 1];
     }
 
 
     @Override
     public boolean isEnabled(int position) {
         // Don't want the user selecting the header.
-        return (getType(position) != TYPE_HEADER);
+        final int type = getType(position);
+        return type != TYPE_DEAD_HEADER && type != TYPE_HEADER;
     }
 
     @Override
@@ -435,4 +458,24 @@
         mRecentFolderList = mRecentFolders.getRecentFolderList(mCurrentFolder);
         notifyDataSetChanged();
     }
+
+    /**
+     * Disable recent folders. Can be enabled again with {@link #enableRecentFolders()}
+     */
+    public void disableRecentFolders() {
+        if (mRecentFoldersVisible) {
+            notifyDataSetChanged();
+            mRecentFoldersVisible = false;
+        }
+    }
+
+    /**
+     * Enable recent folders. Can be disabled again with {@link #disableRecentFolders()}
+     */
+    public void enableRecentFolders() {
+        if (!mRecentFoldersVisible) {
+            notifyDataSetChanged();
+            mRecentFoldersVisible = true;
+        }
+    }
 }
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index dd5d2ff..08bf9e8 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -74,7 +74,6 @@
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Set;
diff --git a/src/com/android/mail/ui/MailActionBarView.java b/src/com/android/mail/ui/MailActionBarView.java
index 0878f3b..591131d 100644
--- a/src/com/android/mail/ui/MailActionBarView.java
+++ b/src/com/android/mail/ui/MailActionBarView.java
@@ -26,7 +26,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -38,7 +37,6 @@
 import android.widget.Toast;
 
 import com.android.mail.AccountSpinnerAdapter;
-import com.android.mail.ConversationListContext;
 import com.android.mail.R;
 import com.android.mail.browse.SnippetTextView;
 import com.android.mail.providers.Account;
@@ -87,6 +85,10 @@
     private MenuItem mFolderSettingsItem;
     private View mRefreshActionView;
     private boolean mRefreshInProgress;
+    /**
+     * True if we are running on tablet.
+     */
+    private final boolean mIsOnTablet;
 
     public static final String LOG_TAG = new LogUtils().getLogTag();
 
@@ -114,8 +116,8 @@
 
     public MailActionBarView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-
         mShowConversationSubject = getResources().getBoolean(R.bool.show_conversation_subject);
+        mIsOnTablet = Utils.useTabletUI(context);
     }
 
     @Override
@@ -367,6 +369,15 @@
         // Always update the options menu and redraw. This will read the new mode and redraw
         // the options menu.
         mActivity.invalidateOptionsMenu();
+        // If we are running on a tablet, we need to enable recent folders only in conversation
+        // view, and disable them everywhere else.
+        if (mIsOnTablet) {
+            if (mMode == ViewMode.CONVERSATION) {
+                mSpinner.enableRecentFolders();
+            } else {
+                mSpinner.disableRecentFolders();
+            }
+        }
     }
 
     protected int getMode() {