Merge "[Quantum search] new two-pane land search result list" into ub-gmail-ur14-dev
diff --git a/res/layout/mail_actionbar_searchview.xml b/res/layout/mail_actionbar_searchview.xml
index 62164a8..7a253b6 100644
--- a/res/layout/mail_actionbar_searchview.xml
+++ b/res/layout/mail_actionbar_searchview.xml
@@ -30,8 +30,6 @@
         android:layout_height="match_parent"
         android:background="?android:attr/selectableItemBackground"
         android:contentDescription="@string/search_back_desc"
-        android:paddingLeft="@dimen/search_button_padding"
-        android:paddingRight="@dimen/search_button_padding"
         android:scaleType="center"
         android:src="@drawable/ic_arrow_back_24dp_with_rtl" />
 
@@ -59,8 +57,6 @@
         android:layout_width="@dimen/search_ending_button_width"
         android:layout_height="match_parent"
         android:background="?android:attr/selectableItemBackground"
-        android:paddingLeft="@dimen/search_button_padding"
-        android:paddingRight="@dimen/search_button_padding"
         android:scaleType="center" />
 
 </com.android.mail.ui.MaterialSearchActionView>
\ No newline at end of file
diff --git a/res/layout/one_pane_activity.xml b/res/layout/one_pane_activity.xml
index c76beed..ef0464b 100644
--- a/res/layout/one_pane_activity.xml
+++ b/res/layout/one_pane_activity.xml
@@ -33,7 +33,7 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:foregroundGravity="fill_horizontal|top"
-            android:foreground="?android:attr/windowContentOverlay" >
+            android:foreground="?android:attr/windowContentOverlay">
 
             <FrameLayout
                 android:id="@+id/content_pane"
diff --git a/res/layout/search_suggestion_item.xml b/res/layout/search_suggestion_item.xml
index c53f426..6f03117 100644
--- a/res/layout/search_suggestion_item.xml
+++ b/res/layout/search_suggestion_item.xml
@@ -26,8 +26,6 @@
         android:id="@+id/search_overlay_item_icon"
         android:layout_width="@dimen/search_leading_button_width"
         android:layout_height="wrap_content"
-        android:paddingLeft="@dimen/search_button_padding"
-        android:paddingRight="@dimen/search_button_padding"
         android:scaleType="center" />
 
     <TextView
diff --git a/res/layout/two_pane_activity.xml b/res/layout/two_pane_activity.xml
index ca11599..3b9ef33 100644
--- a/res/layout/two_pane_activity.xml
+++ b/res/layout/two_pane_activity.xml
@@ -26,14 +26,14 @@
     <!-- Main content -->
     <FrameLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent"
+        android:foreground="?android:attr/windowContentOverlay">
 
         <com.android.mail.ui.TwoPaneLayout
             android:id="@+id/two_pane_activity"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:foregroundGravity="fill_horizontal|top"
-            android:foreground="?android:attr/windowContentOverlay"
             android:background="@color/tablet_background_gray">
 
             <FrameLayout
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 9579236..aa76131 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -22,6 +22,7 @@
     <color name="accent_blue">#4285f4</color>
     <color name="text_color_blue">@color/accent_blue</color>
     <color name="text_color_draft_red">#da4336</color>
+    <color name="text_color_hint_grey">#949494</color>
     <color name="gray_text_color">#777777</color>
     <color name="dark_gray_text_color">#58585b</color>
     <color name="light_gray">#cccccc</color>
@@ -58,7 +59,7 @@
     <!-- Compose colors -->
     <color name="compose_label_text">@color/text_color_grey</color>
     <color name="compose_user_text">@color/text_color_black</color>
-    <color name="compose_label_hint">#999999</color>
+    <color name="compose_label_hint">@color/text_color_hint_grey</color>
     <color name="compose_divider_color">@color/light_gray</color>
     <!-- Must match the quoted_text_background_color_string -->
     <color name="compose_background_color">@android:color/white</color>
@@ -75,7 +76,7 @@
     <color name="conversation_view_text_color_light">@color/text_color_grey</color>
     <color name="conversation_view_text_color_dark">@color/text_color_black</color>
     <color name="conversation_view_text_color_link_blue">@color/text_color_blue</color>
-    <color name="conversation_view_footer_text_color">#999999</color>
+    <color name="conversation_view_footer_text_color">#a7a7a7</color>
 
     <!-- Widget colors -->
     <color name="widget_header_bg_color">#da4336</color>
@@ -84,7 +85,7 @@
     <!--  Color of the semi-transparent shadow box on attachment tiles -->
     <color name="attachment_tile_shadow_box_color">#7F000000</color>
     <!--  Color of the subtitle message in the attachment tile -->
-    <color name="attachment_tile_subtitle_color">#999999</color>
+    <color name="attachment_tile_subtitle_color">@color/text_color_hint_grey</color>
     <color name="attachment_image_background_color">#E5E5E5</color>
 
     <!-- Color of the parent folders and dividers for hierarchical folder descriptions in the move to folder -->
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 54be9dc..f071ea4 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -147,8 +147,7 @@
     <dimen name="widget_senders_padding_end">16dip</dimen>
     <dimen name="widget_attachment_padding_end">8dp</dimen>
 
-    <dimen name="search_leading_button_width">72dp</dimen>
-    <dimen name="search_button_padding">16dp</dimen>
+    <dimen name="search_leading_button_width">56dp</dimen>
     <dimen name="search_main_text_padding">16dp</dimen>
     <dimen name="search_ending_button_width">56dp</dimen>
     <dimen name="search_suggestion_padding">16dp</dimen>
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index c062d72..ef0355d 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -132,6 +132,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
+import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -220,8 +221,10 @@
     // the previously instantiated map.  If ComposeActivity.onCreate() is called, with a bundle
     // (restoring data from a previous instance), and the map hasn't been created, we will attempt
     // to populate the map with data stored in shared preferences.
-    // FIXME: values in this map are never read.
-    private static ConcurrentHashMap<Integer, Long> sRequestMessageIdMap = null;
+    private static final ConcurrentHashMap<Integer, Long> sRequestMessageIdMap =
+            new ConcurrentHashMap<Integer, Long>(10);
+    private static final Random sRandom = new Random(System.currentTimeMillis());
+
     /**
      * Notifies the {@code Activity} that the caller is an Email
      * {@code Activity}, so that the back behavior may be modified accordingly.
@@ -333,7 +336,7 @@
     protected Bundle mInnerSavedState;
     private ContentValues mExtraValues = null;
 
-    // FIXME: this variable is never read. related to sRequestMessageIdMap.
+    // This is used to track pending requests, refer to sRequestMessageIdMap
     private int mRequestId;
     private String mSignature;
     private Account[] mAccounts;
@@ -528,6 +531,16 @@
             quotedText = savedState.getCharSequence(EXTRA_QUOTED_TEXT);
 
             mExtraValues = savedState.getParcelable(EXTRA_VALUES);
+
+            // Get the draft id from the request id if there is one.
+            if (savedState.containsKey(EXTRA_REQUEST_ID)) {
+                final int requestId = savedState.getInt(EXTRA_REQUEST_ID);
+                if (sRequestMessageIdMap.containsKey(requestId)) {
+                    synchronized (mDraftLock) {
+                        mDraftId = sRequestMessageIdMap.get(requestId);
+                    }
+                }
+            }
         } else {
             account = obtainAccount(intent);
             action = intent.getIntExtra(EXTRA_ACTION, COMPOSE);
@@ -1515,10 +1528,17 @@
     }
 
     private void initFromDraftMessage(Message message) {
-        LogUtils.d(LOG_TAG, "Intializing draft from previous draft message: %s", message);
+        LogUtils.d(LOG_TAG, "Initializing draft from previous draft message: %s", message);
 
-        mDraft = message;
-        mDraftId = message.id;
+        synchronized (mDraftLock) {
+            // Draft id might already be set by the request to id map, if so we don't need to set it
+            if (mDraftId == UIProvider.INVALID_MESSAGE_ID) {
+                mDraftId = message.id;
+            } else {
+                message.id = mDraftId;
+            }
+            mDraft = message;
+        }
         mSubject.setText(message.subject);
         mForward = message.draftType == UIProvider.DraftType.FORWARD;
 
@@ -2446,27 +2466,26 @@
     public interface SendOrSaveCallback {
         void initializeSendOrSave();
         void notifyMessageIdAllocated(SendOrSaveMessage sendOrSaveMessage, Message message);
-        Message getMessage();
+        long getMessageId();
         void sendOrSaveFinished(SendOrSaveMessage message, boolean success);
     }
 
     private void runSendOrSaveProviderCalls(SendOrSaveMessage sendOrSaveMessage,
-            SendOrSaveCallback callback, ReplyFromAccount draftAccount) {
-        final ReplyFromAccount selectedAccount = sendOrSaveMessage.mAccount;
-        Message message = callback.getMessage();
-        long messageId = message != null ? message.id : UIProvider.INVALID_MESSAGE_ID;
+            SendOrSaveCallback callback, ReplyFromAccount currReplyFromAccount,
+            ReplyFromAccount originalReplyFromAccount) {
+        long messageId = callback.getMessageId();
         // If a previous draft has been saved, in an account that is different
         // than what the user wants to send from, remove the old draft, and treat this
         // as a new message
-        if (draftAccount != null
-                && !selectedAccount.account.uri.equals(draftAccount.account.uri)) {
+        if (originalReplyFromAccount != null
+                && !currReplyFromAccount.account.uri.equals(originalReplyFromAccount.account.uri)) {
             if (messageId != UIProvider.INVALID_MESSAGE_ID) {
                 ContentResolver resolver = getContentResolver();
                 ContentValues values = new ContentValues();
                 values.put(BaseColumns._ID, messageId);
-                if (draftAccount.account.expungeMessageUri != null) {
+                if (originalReplyFromAccount.account.expungeMessageUri != null) {
                     new ContentProviderTask.UpdateTask()
-                            .run(resolver, draftAccount.account.expungeMessageUri,
+                            .run(resolver, originalReplyFromAccount.account.expungeMessageUri,
                                     values, null, null);
                 } else {
                     // TODO(mindyp) delete the conversation.
@@ -2477,7 +2496,7 @@
         }
 
         final long messageIdToSave = messageId;
-        sendOrSaveMessage(callback, messageIdToSave, sendOrSaveMessage, selectedAccount);
+        sendOrSaveMessage(callback, messageIdToSave, sendOrSaveMessage, currReplyFromAccount);
 
         if (!sendOrSaveMessage.mSave) {
             incrementRecipientsTimesContacted(
@@ -2629,22 +2648,20 @@
 
     @VisibleForTesting
     public static class SendOrSaveMessage {
-        final ReplyFromAccount mAccount;
+        final int mRequestId;
         final ContentValues mValues;
         final String mRefMessageId;
         @VisibleForTesting
         public final boolean mSave;
-        final int mRequestId;
         private final Bundle mAttachmentFds;
 
-        public SendOrSaveMessage(Context context, ReplyFromAccount account, ContentValues values,
+        public SendOrSaveMessage(Context context, int requestId, ContentValues values,
                 String refMessageId, List<Attachment> attachments, Bundle optionalAttachmentFds,
                 boolean save) {
-            mAccount = account;
+            mRequestId = requestId;
             mValues = values;
             mRefMessageId = refMessageId;
             mSave = save;
-            mRequestId = mValues.hashCode() ^ hashCode();
 
             // If the attachments are already open for us (pre-JB), then don't open them again
             if (optionalAttachmentFds != null) {
@@ -2654,10 +2671,6 @@
             }
         }
 
-        int requestId() {
-            return mRequestId;
-        }
-
         Bundle attachmentFds() {
             return mAttachmentFds;
         }
@@ -3095,10 +3108,10 @@
         return mSubject.getText().toString();
     }
 
-    private int sendOrSaveInternal(Context context, ReplyFromAccount replyFromAccount,
-            Message message, final Message refMessage, final CharSequence quotedText,
-            SendOrSaveCallback callback, boolean save, int composeMode,
-            ReplyFromAccount draftAccount, final ContentValues extraValues,
+    private void sendOrSaveInternal(Context context, int requestId,
+            ReplyFromAccount currReplyFromAccount, ReplyFromAccount originalReplyFromAccount,
+            Message message, Message refMessage, CharSequence quotedText,
+            SendOrSaveCallback callback, boolean save, int composeMode, ContentValues extraValues,
             Bundle optionalAttachmentFds) {
         final ContentValues values = new ContentValues();
 
@@ -3174,16 +3187,13 @@
             values.putAll(extraValues);
         }
 
-        SendOrSaveMessage sendOrSaveMessage = new SendOrSaveMessage(context, replyFromAccount,
+        SendOrSaveMessage sendOrSaveMessage = new SendOrSaveMessage(context, requestId,
                 values, refMessageId, message.getAttachments(), optionalAttachmentFds, save);
-        runSendOrSaveProviderCalls(sendOrSaveMessage, callback, draftAccount);
+        runSendOrSaveProviderCalls(sendOrSaveMessage, callback, currReplyFromAccount, originalReplyFromAccount);
 
         LogUtils.i(LOG_TAG, "[compose] SendOrSaveMessage [%s] posted (isSave: %s) - " +
-                        "body length: %d, attachment count: %d",
-                sendOrSaveMessage.requestId(), save, message.bodyText.length(),
+                "body length: %d, attachment count: %d", requestId, save, message.bodyText.length(),
                 message.getAttachmentCount(true));
-
-        return sendOrSaveMessage.requestId();
     }
 
     /**
@@ -3247,9 +3257,6 @@
         }
 
         final SendOrSaveCallback callback = new SendOrSaveCallback() {
-            // FIXME: unused
-            private int mRestoredRequestId;
-
             @Override
             public void initializeSendOrSave() {
                 final Intent i = new Intent(ComposeActivity.this, EmptyService.class);
@@ -3292,11 +3299,10 @@
             public void notifyMessageIdAllocated(SendOrSaveMessage sendOrSaveMessage,
                     Message message) {
                 synchronized (mDraftLock) {
-                    mDraftAccount = sendOrSaveMessage.mAccount;
                     mDraftId = message.id;
                     mDraft = message;
                     if (sRequestMessageIdMap != null) {
-                        sRequestMessageIdMap.put(sendOrSaveMessage.requestId(), mDraftId);
+                        sRequestMessageIdMap.put(sendOrSaveMessage.mRequestId, mDraftId);
                     }
                     // Cache request message map, in case the process is killed
                     saveRequestMap();
@@ -3307,9 +3313,9 @@
             }
 
             @Override
-            public Message getMessage() {
+            public long getMessageId() {
                 synchronized (mDraftLock) {
-                    return mDraft;
+                    return mDraftId;
                 }
             }
 
@@ -3354,13 +3360,15 @@
             attachmentFds = null;
         }
 
+        // Generate a unique message id for this request
+        mRequestId = sRandom.nextInt();
         SEND_SAVE_TASK_HANDLER.post(new Runnable() {
             @Override
             public void run() {
                 final Message msg = createMessage(mReplyFromAccount, mRefMessage, getMode(), body);
-                mRequestId = sendOrSaveInternal(ComposeActivity.this, mReplyFromAccount, msg,
-                        mRefMessage, mQuotedTextView.getQuotedTextIfIncluded(), callback,
-                        save, mComposeMode, mDraftAccount, mExtraValues, attachmentFds);
+                sendOrSaveInternal(ComposeActivity.this, mRequestId, mReplyFromAccount,
+                        mDraftAccount, msg, mRefMessage, mQuotedTextView.getQuotedTextIfIncluded(),
+                        callback, save, mComposeMode, mExtraValues, attachmentFds);
             }
         });
 
diff --git a/src/com/android/mail/ui/MaterialSearchActionView.java b/src/com/android/mail/ui/MaterialSearchActionView.java
index e9b31e7..d7ad5a3 100644
--- a/src/com/android/mail/ui/MaterialSearchActionView.java
+++ b/src/com/android/mail/ui/MaterialSearchActionView.java
@@ -25,7 +25,10 @@
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
+import android.view.ActionMode;
 import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
@@ -150,6 +153,27 @@
         mQueryText.setOnClickListener(this);
         mQueryText.setOnEditorActionListener(this);
         mQueryText.setOnKeyListener(this);
+        // Disable CAB for search edittext
+        mQueryText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
+            @Override
+            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+                return false;
+            }
+
+            @Override
+            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+                return false;
+            }
+
+            @Override
+            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+                return false;
+            }
+
+            @Override
+            public void onDestroyActionMode(ActionMode mode) {
+            }
+        });
         mEndingButton = (ImageView) findViewById(R.id.search_actionbar_ending_button);
         mEndingButton.setOnClickListener(this);
         setupEndingButton(mQueryText.getText());